[io-layer] Extract GetThreadPriority and SetThreadPriority
[mono.git] / mono / io-layer / versioninfo.c
index 0d2ae600d1293d142b30f676395a08f44f2d6e57..6b811b0a3bfec31f8add6846cf568d311c1e185b 100644 (file)
@@ -11,7 +11,6 @@
 #include <glib.h>
 #include <string.h>
 #include <pthread.h>
-#include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <mono/io-layer/versioninfo.h>
 #include <mono/io-layer/io-portability.h>
 #include <mono/io-layer/error.h>
+#include <mono/io-layer/io-trace.h>
 #include <mono/utils/strenc.h>
-
-#undef DEBUG
+#include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-logger-internals.h>
 
 #define ALIGN32(ptr) ptr = (gpointer)((char *)ptr + 3); ptr = (gpointer)((char *)ptr - ((gsize)ptr & 3));
 
-static WapiImageSectionHeader *get_enclosing_section_header (guint32 rva, WapiImageNTHeaders32 *nt_headers)
+static WapiImageSectionHeader *
+get_enclosing_section_header (guint32 rva, WapiImageNTHeaders32 *nt_headers)
 {
        WapiImageSectionHeader *section = _WAPI_IMAGE_FIRST_SECTION32 (nt_headers);
        guint32 i;
@@ -52,8 +53,8 @@ static WapiImageSectionHeader *get_enclosing_section_header (guint32 rva, WapiIm
 /* This works for both 32bit and 64bit files, as the differences are
  * all after the section header block
  */
-static gpointer get_ptr_from_rva (guint32 rva, WapiImageNTHeaders32 *ntheaders,
-                                 gpointer file_map)
+static gpointer
+get_ptr_from_rva (guint32 rva, WapiImageNTHeaders32 *ntheaders, gpointer file_map)
 {
        WapiImageSectionHeader *section_header;
        guint32 delta;
@@ -69,12 +70,13 @@ static gpointer get_ptr_from_rva (guint32 rva, WapiImageNTHeaders32 *ntheaders,
        return((guint8 *)file_map + rva - delta);
 }
 
-static gpointer scan_resource_dir (WapiImageResourceDirectory *root,
-                                  WapiImageNTHeaders32 *nt_headers,
-                                  gpointer file_map,
-                                  WapiImageResourceDirectoryEntry *entry,
-                                  int level, guint32 res_id, guint32 lang_id,
-                                  guint32 *size)
+static gpointer
+scan_resource_dir (WapiImageResourceDirectory *root,
+                  WapiImageNTHeaders32 *nt_headers,
+                  gpointer file_map,
+                  WapiImageResourceDirectoryEntry *entry,
+                  int level, guint32 res_id, guint32 lang_id,
+                  guint32 *size)
 {
        WapiImageResourceDirectoryEntry swapped_entry;
        gboolean is_string, is_dir;
@@ -143,9 +145,10 @@ static gpointer scan_resource_dir (WapiImageResourceDirectory *root,
        }
 }
 
-static gpointer find_pe_file_resources32 (gpointer file_map, guint32 map_size,
-                                         guint32 res_id, guint32 lang_id,
-                                         guint32 *size)
+static gpointer
+find_pe_file_resources32 (gpointer file_map, guint32 map_size,
+                         guint32 res_id, guint32 lang_id,
+                         guint32 *size)
 {
        WapiImageDosHeader *dos_header;
        WapiImageNTHeaders32 *nt_headers;
@@ -156,19 +159,14 @@ static gpointer find_pe_file_resources32 (gpointer file_map, guint32 map_size,
 
        dos_header = (WapiImageDosHeader *)file_map;
        if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
-#ifdef DEBUG
-               g_message ("%s: Bad dos signature 0x%x", __func__,
-                          dos_header->e_magic);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad dos signature 0x%x", __func__, dos_header->e_magic);
 
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
        }
        
        if (map_size < sizeof(WapiImageNTHeaders32) + GUINT32_FROM_LE (dos_header->e_lfanew)) {
-#ifdef DEBUG
-               g_message ("%s: File is too small: %d", __func__, map_size);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File is too small: %d", __func__, map_size);
 
                SetLastError (ERROR_BAD_LENGTH);
                return(NULL);
@@ -176,10 +174,7 @@ static gpointer find_pe_file_resources32 (gpointer file_map, guint32 map_size,
        
        nt_headers = (WapiImageNTHeaders32 *)((guint8 *)file_map + GUINT32_FROM_LE (dos_header->e_lfanew));
        if (nt_headers->Signature != IMAGE_NT_SIGNATURE) {
-#ifdef DEBUG
-               g_message ("%s: Bad NT signature 0x%x", __func__,
-                          nt_headers->Signature);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad NT signature 0x%x", __func__, nt_headers->Signature);
 
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
@@ -193,18 +188,16 @@ static gpointer find_pe_file_resources32 (gpointer file_map, guint32 map_size,
        }
 
        if (resource_rva == 0) {
-#ifdef DEBUG
-               g_message ("%s: No resources in file!", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No resources in file!", __func__);
+
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
        }
        
        resource_dir = (WapiImageResourceDirectory *)get_ptr_from_rva (resource_rva, (WapiImageNTHeaders32 *)nt_headers, file_map);
        if (resource_dir == NULL) {
-#ifdef DEBUG
-               g_message ("%s: Can't find resource directory", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find resource directory", __func__);
+
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
        }
@@ -226,9 +219,10 @@ static gpointer find_pe_file_resources32 (gpointer file_map, guint32 map_size,
        return(NULL);
 }
 
-static gpointer find_pe_file_resources64 (gpointer file_map, guint32 map_size,
-                                         guint32 res_id, guint32 lang_id,
-                                         guint32 *size)
+static gpointer
+find_pe_file_resources64 (gpointer file_map, guint32 map_size,
+                         guint32 res_id, guint32 lang_id,
+                         guint32 *size)
 {
        WapiImageDosHeader *dos_header;
        WapiImageNTHeaders64 *nt_headers;
@@ -239,19 +233,14 @@ static gpointer find_pe_file_resources64 (gpointer file_map, guint32 map_size,
 
        dos_header = (WapiImageDosHeader *)file_map;
        if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
-#ifdef DEBUG
-               g_message ("%s: Bad dos signature 0x%x", __func__,
-                          dos_header->e_magic);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad dos signature 0x%x", __func__, dos_header->e_magic);
 
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
        }
        
        if (map_size < sizeof(WapiImageNTHeaders64) + GUINT32_FROM_LE (dos_header->e_lfanew)) {
-#ifdef DEBUG
-               g_message ("%s: File is too small: %d", __func__, map_size);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File is too small: %d", __func__, map_size);
 
                SetLastError (ERROR_BAD_LENGTH);
                return(NULL);
@@ -259,10 +248,8 @@ static gpointer find_pe_file_resources64 (gpointer file_map, guint32 map_size,
        
        nt_headers = (WapiImageNTHeaders64 *)((guint8 *)file_map + GUINT32_FROM_LE (dos_header->e_lfanew));
        if (nt_headers->Signature != IMAGE_NT_SIGNATURE) {
-#ifdef DEBUG
-               g_message ("%s: Bad NT signature 0x%x", __func__,
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad NT signature 0x%x", __func__,
                           nt_headers->Signature);
-#endif
 
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
@@ -276,18 +263,16 @@ static gpointer find_pe_file_resources64 (gpointer file_map, guint32 map_size,
        }
 
        if (resource_rva == 0) {
-#ifdef DEBUG
-               g_message ("%s: No resources in file!", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No resources in file!", __func__);
+
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
        }
        
        resource_dir = (WapiImageResourceDirectory *)get_ptr_from_rva (resource_rva, (WapiImageNTHeaders32 *)nt_headers, file_map);
        if (resource_dir == NULL) {
-#ifdef DEBUG
-               g_message ("%s: Can't find resource directory", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find resource directory", __func__);
+
                SetLastError (ERROR_INVALID_DATA);
                return(NULL);
        }
@@ -309,9 +294,10 @@ static gpointer find_pe_file_resources64 (gpointer file_map, guint32 map_size,
        return(NULL);
 }
 
-static gpointer find_pe_file_resources (gpointer file_map, guint32 map_size,
-                                       guint32 res_id, guint32 lang_id,
-                                       guint32 *size)
+static gpointer
+find_pe_file_resources (gpointer file_map, guint32 map_size,
+                       guint32 res_id, guint32 lang_id,
+                       guint32 *size)
 {
        /* Figure this out when we support 64bit PE files */
        if (1) {
@@ -323,7 +309,8 @@ static gpointer find_pe_file_resources (gpointer file_map, guint32 map_size,
        }
 }
 
-static gpointer map_pe_file (gunichar2 *filename, guint32 *map_size)
+static gpointer
+map_pe_file (gunichar2 *filename, gint32 *map_size, void **handle)
 {
        gchar *filename_ext;
        int fd;
@@ -337,9 +324,7 @@ static gpointer map_pe_file (gunichar2 *filename, guint32 *map_size)
 
        filename_ext = mono_unicode_to_external (filename);
        if (filename_ext == NULL) {
-#ifdef DEBUG
-               g_message ("%s: unicode conversion returned NULL", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
 
                SetLastError (ERROR_INVALID_NAME);
                return(NULL);
@@ -347,10 +332,7 @@ static gpointer map_pe_file (gunichar2 *filename, guint32 *map_size)
        
        fd = _wapi_open (filename_ext, O_RDONLY, 0);
        if (fd == -1) {
-#ifdef DEBUG
-               g_message ("%s: Error opening file %s: %s", __func__,
-                          filename_ext, strerror (errno));
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error opening file %s: %s", __func__, filename_ext, strerror (errno));
 
                SetLastError (_wapi_get_win32_file_error (errno));
                g_free (filename_ext);
@@ -359,10 +341,7 @@ static gpointer map_pe_file (gunichar2 *filename, guint32 *map_size)
        }
 
        if (fstat (fd, &statbuf) == -1) {
-#ifdef DEBUG
-               g_message ("%s: Error stat()ing file %s: %s", __func__,
-                          filename_ext, strerror (errno));
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error stat()ing file %s: %s", __func__, filename_ext, strerror (errno));
 
                SetLastError (_wapi_get_win32_file_error (errno));
                g_free (filename_ext);
@@ -370,13 +349,10 @@ static gpointer map_pe_file (gunichar2 *filename, guint32 *map_size)
                return(NULL);
        }
        *map_size = statbuf.st_size;
-
+       
        /* Check basic file size */
        if (statbuf.st_size < sizeof(WapiImageDosHeader)) {
-#ifdef DEBUG
-               g_message ("%s: File %s is too small: %lld", __func__,
-                          filename_ext, statbuf.st_size);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File %s is too small: %lld", __func__, filename_ext, statbuf.st_size);
 
                SetLastError (ERROR_BAD_LENGTH);
                g_free (filename_ext);
@@ -384,12 +360,9 @@ static gpointer map_pe_file (gunichar2 *filename, guint32 *map_size)
                return(NULL);
        }
        
-       file_map = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-       if (file_map == MAP_FAILED) {
-#ifdef DEBUG
-               g_message ("%s: Error mmap()int file %s: %s", __func__,
-                          filename_ext, strerror (errno));
-#endif
+       file_map = mono_file_map (statbuf.st_size, MONO_MMAP_READ | MONO_MMAP_PRIVATE, fd, 0, handle);
+       if (file_map == NULL) {
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error mmap()int file %s: %s", __func__, filename_ext, strerror (errno));
 
                SetLastError (_wapi_get_win32_file_error (errno));
                g_free (filename_ext);
@@ -399,16 +372,19 @@ static gpointer map_pe_file (gunichar2 *filename, guint32 *map_size)
 
        /* Don't need the fd any more */
        close (fd);
+       g_free (filename_ext);
 
        return(file_map);
 }
 
-static void unmap_pe_file (gpointer file_map, guint32 map_size)
+static void
+unmap_pe_file (gpointer file_map, void *handle)
 {
-       munmap (file_map, map_size);
+       mono_file_unmap (file_map, handle);
 }
 
-static guint32 unicode_chars (const gunichar2 *str)
+static guint32
+unicode_chars (const gunichar2 *str)
 {
        guint32 len = 0;
        
@@ -420,7 +396,8 @@ static guint32 unicode_chars (const gunichar2 *str)
        } while(1);
 }
 
-static gboolean unicode_compare (const gunichar2 *str1, const gunichar2 *str2)
+static gboolean
+unicode_compare (const gunichar2 *str1, const gunichar2 *str2)
 {
        while (*str1 && *str2) {
                if (*str1 != *str2) {
@@ -436,7 +413,8 @@ static gboolean unicode_compare (const gunichar2 *str1, const gunichar2 *str2)
 /* compare a little-endian null-terminated utf16 string and a normal string.
  * Can be used only for ascii or latin1 chars.
  */
-static gboolean unicode_string_equals (const gunichar2 *str1, const gchar *str2)
+static gboolean
+unicode_string_equals (const gunichar2 *str1, const gchar *str2)
 {
        while (*str1 && *str2) {
                if (GUINT16_TO_LE (*str1) != *str2) {
@@ -460,8 +438,8 @@ typedef struct
 /* Returns a pointer to the value data, because there's no way to know
  * how big that data is (value_len is set to zero for most blocks :-( )
  */
-static gconstpointer get_versioninfo_block (gconstpointer data,
-                                           version_data *block)
+static gconstpointer
+get_versioninfo_block (gconstpointer data, version_data *block)
 {
        block->data_len = GUINT16_FROM_LE (*((guint16 *)data));
        data = (char *)data + sizeof(guint16);
@@ -482,44 +460,38 @@ static gconstpointer get_versioninfo_block (gconstpointer data,
        return(data);
 }
 
-static gconstpointer get_fixedfileinfo_block (gconstpointer data,
-                                             version_data *block)
+static gconstpointer
+get_fixedfileinfo_block (gconstpointer data, version_data *block)
 {
        gconstpointer data_ptr;
-       gint32 data_len; /* signed to guard against underflow */
        WapiFixedFileInfo *ffi;
 
        data_ptr = get_versioninfo_block (data, block);
-       data_len = block->data_len;
                
        if (block->value_len != sizeof(WapiFixedFileInfo)) {
-#ifdef DEBUG
-               g_message ("%s: FIXEDFILEINFO size mismatch", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: FIXEDFILEINFO size mismatch", __func__);
                return(NULL);
        }
 
        if (!unicode_string_equals (block->key, "VS_VERSION_INFO")) {
-#ifdef DEBUG
-               g_message ("%s: VS_VERSION_INFO mismatch", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: VS_VERSION_INFO mismatch", __func__);
+
                return(NULL);
        }
 
        ffi = ((WapiFixedFileInfo *)data_ptr);
        if ((ffi->dwSignature != VS_FFI_SIGNATURE) ||
            (ffi->dwStrucVersion != VS_FFI_STRUCVERSION)) {
-#ifdef DEBUG
-               g_message ("%s: FIXEDFILEINFO bad signature", __func__);
-#endif
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: FIXEDFILEINFO bad signature", __func__);
+
                return(NULL);
        }
 
        return(data_ptr);
 }
 
-static gconstpointer get_varfileinfo_block (gconstpointer data_ptr,
-                                           version_data *block)
+static gconstpointer
+get_varfileinfo_block (gconstpointer data_ptr, version_data *block)
 {
        /* data is pointing at a Var block
         */
@@ -528,11 +500,12 @@ static gconstpointer get_varfileinfo_block (gconstpointer data_ptr,
        return(data_ptr);
 }
 
-static gconstpointer get_string_block (gconstpointer data_ptr,
-                                      const gunichar2 *string_key,
-                                      gpointer *string_value,
-                                      guint32 *string_value_len,
-                                      version_data *block)
+static gconstpointer
+get_string_block (gconstpointer data_ptr,
+                 const gunichar2 *string_key,
+                 gpointer *string_value,
+                 guint32 *string_value_len,
+                 version_data *block)
 {
        guint16 data_len = block->data_len;
        guint16 string_len = 28; /* Length of the StringTable block */
@@ -551,10 +524,8 @@ static gconstpointer get_string_block (gconstpointer data_ptr,
                        /* We must have hit padding, so give up
                         * processing now
                         */
-#ifdef DEBUG
-                       g_message ("%s: Hit 0-length block, giving up",
-                                  __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hit 0-length block, giving up", __func__);
+
                        return(NULL);
                }
                
@@ -582,16 +553,18 @@ static gconstpointer get_string_block (gconstpointer data_ptr,
  *
  * If lang == NULL it means we're just stepping through this block
  */
-static gconstpointer get_stringtable_block (gconstpointer data_ptr,
-                                           gchar *lang,
-                                           const gunichar2 *string_key,
-                                           gpointer *string_value,
-                                           guint32 *string_value_len,
-                                           version_data *block)
+static gconstpointer
+get_stringtable_block (gconstpointer data_ptr,
+                      gchar *lang,
+                      const gunichar2 *string_key,
+                      gpointer *string_value,
+                      guint32 *string_value_len,
+                      version_data *block)
 {
        guint16 data_len = block->data_len;
        guint16 string_len = 36; /* length of the StringFileInfo block */
        gchar *found_lang;
+       gchar *lowercase_lang;
        
        /* data_ptr is pointing at an array of StringTable blocks,
         * with total length (not including alignment padding) of
@@ -607,10 +580,7 @@ static gconstpointer get_stringtable_block (gconstpointer data_ptr,
                        /* We must have hit padding, so give up
                         * processing now
                         */
-#ifdef DEBUG
-                       g_message ("%s: Hit 0-length block, giving up",
-                                  __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hit 0-length block, giving up", __func__);
                        return(NULL);
                }
                
@@ -618,13 +588,14 @@ static gconstpointer get_stringtable_block (gconstpointer data_ptr,
 
                found_lang = g_utf16_to_utf8 (block->key, 8, NULL, NULL, NULL);
                if (found_lang == NULL) {
-#ifdef DEBUG
-                       g_message ("%s: Didn't find a valid language key, giving up", __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't find a valid language key, giving up", __func__);
                        return(NULL);
                }
                
-               g_strdown (found_lang);
+               lowercase_lang = g_utf8_strdown (found_lang, -1);
+               g_free (found_lang);
+               found_lang = lowercase_lang;
+               lowercase_lang = NULL;
                
                if (lang != NULL && !strcmp (found_lang, lang)) {
                        /* Got the one we're interested in */
@@ -640,9 +611,7 @@ static gconstpointer get_stringtable_block (gconstpointer data_ptr,
                
                if (data_ptr == NULL) {
                        /* Child block hit padding */
-#ifdef DEBUG
-                       g_message ("%s: Child block hit 0-length block, giving up", __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Child block hit 0-length block, giving up", __func__);
                        return(NULL);
                }
        }
@@ -651,8 +620,8 @@ static gconstpointer get_stringtable_block (gconstpointer data_ptr,
 }
 
 #if G_BYTE_ORDER == G_BIG_ENDIAN
-static gconstpointer big_up_string_block (gconstpointer data_ptr,
-                                         version_data *block)
+static gconstpointer
+big_up_string_block (gconstpointer data_ptr, version_data *block)
 {
        guint16 data_len = block->data_len;
        guint16 string_len = 28; /* Length of the StringTable block */
@@ -672,10 +641,7 @@ static gconstpointer big_up_string_block (gconstpointer data_ptr,
                        /* We must have hit padding, so give up
                         * processing now
                         */
-#ifdef DEBUG
-                       g_message ("%s: Hit 0-length block, giving up",
-                                  __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hit 0-length block, giving up", __func__);
                        return(NULL);
                }
                
@@ -686,10 +652,7 @@ static gconstpointer big_up_string_block (gconstpointer data_ptr,
                                       "UTF-16BE", "UTF-16LE", NULL, NULL,
                                       NULL);
                if (big_value == NULL) {
-#ifdef DEBUG
-                       g_message ("%s: Didn't find a valid string, giving up",
-                                  __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't find a valid string, giving up", __func__);
                        return(NULL);
                }
                
@@ -706,9 +669,7 @@ static gconstpointer big_up_string_block (gconstpointer data_ptr,
                                       "UTF-16BE", "UTF-16LE", NULL, NULL,
                                       NULL);
                if (big_value == NULL) {
-#ifdef DEBUG
-                       g_message ("%s: Didn't find a valid data string, giving up", __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't find a valid data string, giving up", __func__);
                        return(NULL);
                }
                memcpy ((gpointer)data_ptr, big_value,
@@ -726,8 +687,8 @@ static gconstpointer big_up_string_block (gconstpointer data_ptr,
  * because the data length does not include padding bytes, so it's not
  * possible to just return the start position + length
  */
-static gconstpointer big_up_stringtable_block (gconstpointer data_ptr,
-                                              version_data *block)
+static gconstpointer
+big_up_stringtable_block (gconstpointer data_ptr, version_data *block)
 {
        guint16 data_len = block->data_len;
        guint16 string_len = 36; /* length of the StringFileInfo block */
@@ -747,10 +708,7 @@ static gconstpointer big_up_stringtable_block (gconstpointer data_ptr,
                        /* We must have hit padding, so give up
                         * processing now
                         */
-#ifdef DEBUG
-                       g_message ("%s: Hit 0-length block, giving up",
-                                  __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hit 0-length block, giving up", __func__);
                        return(NULL);
                }
                
@@ -759,10 +717,7 @@ static gconstpointer big_up_stringtable_block (gconstpointer data_ptr,
                big_value = g_convert ((gchar *)block->key, 16, "UTF-16BE",
                                       "UTF-16LE", NULL, NULL, NULL);
                if (big_value == NULL) {
-#ifdef DEBUG
-                       g_message ("%s: Didn't find a valid string, giving up",
-                                  __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't find a valid string, giving up", __func__);
                        return(NULL);
                }
                
@@ -773,9 +728,7 @@ static gconstpointer big_up_stringtable_block (gconstpointer data_ptr,
                
                if (data_ptr == NULL) {
                        /* Child block hit padding */
-#ifdef DEBUG
-                       g_message ("%s: Child block hit 0-length block, giving up", __func__);
-#endif
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Child block hit 0-length block, giving up", __func__);
                        return(NULL);
                }
        }
@@ -786,7 +739,8 @@ static gconstpointer big_up_stringtable_block (gconstpointer data_ptr,
 /* Follows the data structures and turns all UTF-16 strings from the
  * LE found in the resource section into UTF-16BE
  */
-static void big_up (gconstpointer datablock, guint32 size)
+static void
+big_up (gconstpointer datablock, guint32 size)
 {
        gconstpointer data_ptr;
        gint32 data_len; /* signed to guard against underflow */
@@ -826,10 +780,7 @@ static void big_up (gconstpointer datablock, guint32 size)
                                /* We must have hit padding, so give
                                 * up processing now
                                 */
-#ifdef DEBUG
-                               g_message ("%s: Hit 0-length block, giving up",
-                                          __func__);
-#endif
+                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hit 0-length block, giving up", __func__);
                                return;
                        }
                        
@@ -845,17 +796,13 @@ static void big_up (gconstpointer datablock, guint32 size)
                                                                     &block);
                        } else {
                                /* Bogus data */
-#ifdef DEBUG
-                               g_message ("%s: Not a valid VERSIONINFO child block", __func__);
-#endif
+                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Not a valid VERSIONINFO child block", __func__);
                                return;
                        }
                        
                        if (data_ptr == NULL) {
                                /* Child block hit padding */
-#ifdef DEBUG
-                               g_message ("%s: Child block hit 0-length block, giving up", __func__);
-#endif
+                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Child block hit 0-length block, giving up", __func__);
                                return;
                        }
                }
@@ -863,8 +810,8 @@ static void big_up (gconstpointer datablock, guint32 size)
 }
 #endif
 
-gboolean VerQueryValue (gconstpointer datablock, const gunichar2 *subblock,
-                       gpointer *buffer, guint32 *len)
+gboolean
+VerQueryValue (gconstpointer datablock, const gunichar2 *subblock, gpointer *buffer, guint32 *len)
 {
        gchar *subblock_utf8, *lang_utf8 = NULL;
        gboolean ret = FALSE;
@@ -877,6 +824,7 @@ gboolean VerQueryValue (gconstpointer datablock, const gunichar2 *subblock,
        const gunichar2 *string_key = NULL;
        gpointer string_value = NULL;
        guint32 string_value_len = 0;
+       gchar *lowercase_lang;
        
        subblock_utf8 = g_utf16_to_utf8 (subblock, -1, NULL, NULL, NULL);
        if (subblock_utf8 == NULL) {
@@ -889,7 +837,10 @@ gboolean VerQueryValue (gconstpointer datablock, const gunichar2 *subblock,
                want_string = TRUE;
                memcpy (lang, subblock + 16, 8 * sizeof(gunichar2));
                lang_utf8 = g_utf16_to_utf8 (lang, 8, NULL, NULL, NULL);
-               g_strdown (lang_utf8);
+               lowercase_lang = g_utf8_strdown (lang_utf8, -1);
+               g_free (lang_utf8);
+               lang_utf8 = lowercase_lang;
+               lowercase_lang = NULL;
                string_key = subblock + 25;
        }
        
@@ -923,9 +874,7 @@ gboolean VerQueryValue (gconstpointer datablock, const gunichar2 *subblock,
                                        /* We must have hit padding,
                                         * so give up processing now
                                         */
-#ifdef DEBUG
-                                       g_message ("%s: Hit 0-length block, giving up", __func__);
-#endif
+                                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hit 0-length block, giving up", __func__);
                                        goto done;
                                }
                                
@@ -948,23 +897,19 @@ gboolean VerQueryValue (gconstpointer datablock, const gunichar2 *subblock,
                                            string_value != NULL &&
                                            string_value_len != 0) {
                                                *buffer = string_value;
-                                               *len = unicode_chars (string_value) + 1; /* Include trailing null */
+                                               *len = unicode_chars ((const gunichar2 *)string_value) + 1; /* Include trailing null */
                                                ret = TRUE;
                                                goto done;
                                        }
                                } else {
                                        /* Bogus data */
-#ifdef DEBUG
-                                       g_message ("%s: Not a valid VERSIONINFO child block", __func__);
-#endif
+                                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Not a valid VERSIONINFO child block", __func__);
                                        goto done;
                                }
                                
                                if (data_ptr == NULL) {
                                        /* Child block hit padding */
-#ifdef DEBUG
-                                       g_message ("%s: Child block hit 0-length block, giving up", __func__);
-#endif
+                                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Child block hit 0-length block, giving up", __func__);
                                        goto done;
                                }
                        }
@@ -980,23 +925,24 @@ gboolean VerQueryValue (gconstpointer datablock, const gunichar2 *subblock,
        return(ret);
 }
 
-guint32 GetFileVersionInfoSize (gunichar2 *filename, guint32 *handle)
+guint32
+GetFileVersionInfoSize (gunichar2 *filename, guint32 *handle)
 {
        gpointer file_map;
        gpointer versioninfo;
-       guint32 map_size;
+       void *map_handle;
+       gint32 map_size;
        guint32 size;
-       
+
        /* This value is unused, but set to zero */
        *handle = 0;
        
-       file_map = map_pe_file (filename, &map_size);
+       file_map = map_pe_file (filename, &map_size, &map_handle);
        if (file_map == NULL) {
                return(0);
        }
        
-       versioninfo = find_pe_file_resources (file_map, map_size, RT_VERSION,
-                                             0, &size);
+       versioninfo = find_pe_file_resources (file_map, map_size, RT_VERSION, 0, &size);
        if (versioninfo == NULL) {
                /* Didn't find the resource, so set the return value
                 * to 0
@@ -1004,21 +950,22 @@ guint32 GetFileVersionInfoSize (gunichar2 *filename, guint32 *handle)
                size = 0;
        }
 
-       unmap_pe_file (file_map, map_size);
+       unmap_pe_file (file_map, map_handle);
 
        return(size);
 }
 
-gboolean GetFileVersionInfo (gunichar2 *filename, guint32 handle G_GNUC_UNUSED,
-                            guint32 len, gpointer data)
+gboolean
+GetFileVersionInfo (gunichar2 *filename, guint32 handle G_GNUC_UNUSED, guint32 len, gpointer data)
 {
        gpointer file_map;
        gpointer versioninfo;
-       guint32 map_size;
+       void *map_handle;
+       gint32 map_size;
        guint32 size;
        gboolean ret = FALSE;
        
-       file_map = map_pe_file (filename, &map_size);
+       file_map = map_pe_file (filename, &map_size, &map_handle);
        if (file_map == NULL) {
                return(FALSE);
        }
@@ -1039,13 +986,13 @@ gboolean GetFileVersionInfo (gunichar2 *filename, guint32 handle G_GNUC_UNUSED,
 #endif
        }
 
-       unmap_pe_file (file_map, map_size);
+       unmap_pe_file (file_map, map_handle);
        
        return(ret);
 }
 
-static guint32 copy_lang (gunichar2 *lang_out, guint32 lang_len,
-                         const gchar *text)
+static guint32
+copy_lang (gunichar2 *lang_out, guint32 lang_len, const gchar *text)
 {
        gunichar2 *unitext;
        int chars = strlen (text);
@@ -1069,18 +1016,20 @@ static guint32 copy_lang (gunichar2 *lang_out, guint32 lang_len,
        return(ret);
 }
 
-guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
+guint32
+VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
 {
        int primary, secondary;
-       
+       const char *name = NULL;
+
        primary = lang & 0x3FF;
        secondary = (lang >> 10) & 0x3F;
-       
+
        switch(primary) {
        case 0x00:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Process Default Language"));
+                       name = "Process Default Language";
                        break;
                }
                break;
@@ -1088,72 +1037,72 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Saudi Arabia)"));
+                       name = "Arabic (Saudi Arabia)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Iraq)"));
+                       name = "Arabic (Iraq)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Egypt)"));
+                       name = "Arabic (Egypt)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Libya)"));
+                       name = "Arabic (Libya)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Algeria)"));
+                       name = "Arabic (Algeria)";
                        break;
                case 0x06:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Morocco)"));
+                       name = "Arabic (Morocco)";
                        break;
                case 0x07:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Tunisia)"));
+                       name = "Arabic (Tunisia)";
                        break;
                case 0x08:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Oman)"));
+                       name = "Arabic (Oman)";
                        break;
                case 0x09:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Yemen)"));
+                       name = "Arabic (Yemen)";
                        break;
                case 0x0a:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Syria)"));
+                       name = "Arabic (Syria)";
                        break;
                case 0x0b:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Jordan)"));
+                       name = "Arabic (Jordan)";
                        break;
                case 0x0c:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Lebanon)"));
+                       name = "Arabic (Lebanon)";
                        break;
                case 0x0d:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Kuwait)"));
+                       name = "Arabic (Kuwait)";
                        break;
                case 0x0e:
-                       return(copy_lang (lang_out, lang_len, "Arabic (U.A.E.)"));
+                       name = "Arabic (U.A.E.)";
                        break;
                case 0x0f:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Bahrain)"));
+                       name = "Arabic (Bahrain)";
                        break;
                case 0x10:
-                       return(copy_lang (lang_out, lang_len, "Arabic (Qatar)"));
+                       name = "Arabic (Qatar)";
                        break;
                }
                break;
        case 0x02:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Bulgarian (Bulgaria)"));
+                       name = "Bulgarian (Bulgaria)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Bulgarian"));
+                       name = "Bulgarian";
                        break;
                }
                break;
        case 0x03:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Catalan (Spain)"));
+                       name = "Catalan (Spain)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Catalan"));
+                       name = "Catalan";
                        break;
                }
                break;
@@ -1161,39 +1110,39 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Chinese (Taiwan)"));
+                       name = "Chinese (Taiwan)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Chinese (PRC)"));
+                       name = "Chinese (PRC)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "Chinese (Hong Kong S.A.R.)"));
+                       name = "Chinese (Hong Kong S.A.R.)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "Chinese (Singapore)"));
+                       name = "Chinese (Singapore)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "Chinese (Macau S.A.R.)"));
+                       name = "Chinese (Macau S.A.R.)";
                        break;
                }
                break;
        case 0x05:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Czech (Czech Republic)"));
+                       name = "Czech (Czech Republic)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Czech"));
+                       name = "Czech";
                        break;
                }
                break;
        case 0x06:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Danish (Denmark)"));
+                       name = "Danish (Denmark)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Danish"));
+                       name = "Danish";
                        break;
                }
                break;
@@ -1201,29 +1150,29 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "German (Germany)"));
+                       name = "German (Germany)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "German (Switzerland)"));
+                       name = "German (Switzerland)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "German (Austria)"));
+                       name = "German (Austria)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "German (Luxembourg)"));
+                       name = "German (Luxembourg)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "German (Liechtenstein)"));
+                       name = "German (Liechtenstein)";
                        break;
                }
                break;
        case 0x08:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Greek (Greece)"));
+                       name = "Greek (Greece)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Greek"));
+                       name = "Greek";
                        break;
                }
                break;
@@ -1231,132 +1180,132 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "English (United States)"));
+                       name = "English (United States)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "English (United Kingdom)"));
+                       name = "English (United Kingdom)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "English (Australia)"));
+                       name = "English (Australia)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "English (Canada)"));
+                       name = "English (Canada)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "English (New Zealand)"));
+                       name = "English (New Zealand)";
                        break;
                case 0x06:
-                       return(copy_lang (lang_out, lang_len, "English (Ireland)"));
+                       name = "English (Ireland)";
                        break;
                case 0x07:
-                       return(copy_lang (lang_out, lang_len, "English (South Africa)"));
+                       name = "English (South Africa)";
                        break;
                case 0x08:
-                       return(copy_lang (lang_out, lang_len, "English (Jamaica)"));
+                       name = "English (Jamaica)";
                        break;
                case 0x09:
-                       return(copy_lang (lang_out, lang_len, "English (Caribbean)"));
+                       name = "English (Caribbean)";
                        break;
                case 0x0a:
-                       return(copy_lang (lang_out, lang_len, "English (Belize)"));
+                       name = "English (Belize)";
                        break;
                case 0x0b:
-                       return(copy_lang (lang_out, lang_len, "English (Trinidad and Tobago)"));
+                       name = "English (Trinidad and Tobago)";
                        break;
                case 0x0c:
-                       return(copy_lang (lang_out, lang_len, "English (Zimbabwe)"));
+                       name = "English (Zimbabwe)";
                        break;
                case 0x0d:
-                       return(copy_lang (lang_out, lang_len, "English (Philippines)"));
+                       name = "English (Philippines)";
                        break;
                case 0x10:
-                       return(copy_lang (lang_out, lang_len, "English (India)"));
+                       name = "English (India)";
                        break;
                case 0x11:
-                       return(copy_lang (lang_out, lang_len, "English (Malaysia)"));
+                       name = "English (Malaysia)";
                        break;
                case 0x12:
-                       return(copy_lang (lang_out, lang_len, "English (Singapore)"));
+                       name = "English (Singapore)";
                        break;
                }
                break;
        case 0x0a:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Spain)"));
+                       name = "Spanish (Spain)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Traditional Sort)"));
+                       name = "Spanish (Traditional Sort)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Mexico)"));
+                       name = "Spanish (Mexico)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "Spanish (International Sort)"));
+                       name = "Spanish (International Sort)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Guatemala)"));
+                       name = "Spanish (Guatemala)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Costa Rica)"));
+                       name = "Spanish (Costa Rica)";
                        break;
                case 0x06:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Panama)"));
+                       name = "Spanish (Panama)";
                        break;
                case 0x07:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Dominican Republic)"));
+                       name = "Spanish (Dominican Republic)";
                        break;
                case 0x08:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Venezuela)"));
+                       name = "Spanish (Venezuela)";
                        break;
                case 0x09:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Colombia)"));
+                       name = "Spanish (Colombia)";
                        break;
                case 0x0a:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Peru)"));
+                       name = "Spanish (Peru)";
                        break;
                case 0x0b:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Argentina)"));
+                       name = "Spanish (Argentina)";
                        break;
                case 0x0c:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Ecuador)"));
+                       name = "Spanish (Ecuador)";
                        break;
                case 0x0d:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Chile)"));
+                       name = "Spanish (Chile)";
                        break;
                case 0x0e:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Uruguay)"));
+                       name = "Spanish (Uruguay)";
                        break;
                case 0x0f:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Paraguay)"));
+                       name = "Spanish (Paraguay)";
                        break;
                case 0x10:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Bolivia)"));
+                       name = "Spanish (Bolivia)";
                        break;
                case 0x11:
-                       return(copy_lang (lang_out, lang_len, "Spanish (El Salvador)"));
+                       name = "Spanish (El Salvador)";
                        break;
                case 0x12:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Honduras)"));
+                       name = "Spanish (Honduras)";
                        break;
                case 0x13:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Nicaragua)"));
+                       name = "Spanish (Nicaragua)";
                        break;
                case 0x14:
-                       return(copy_lang (lang_out, lang_len, "Spanish (Puerto Rico)"));
+                       name = "Spanish (Puerto Rico)";
                        break;
                case 0x15:
-                       return(copy_lang (lang_out, lang_len, "Spanish (United States)"));
+                       name = "Spanish (United States)";
                        break;
                }
                break;
        case 0x0b:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Finnish (Finland)"));
+                       name = "Finnish (Finland)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Finnish"));
+                       name = "Finnish";
                        break;
                }
                break;
@@ -1364,52 +1313,52 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "French (France)"));
+                       name = "French (France)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "French (Belgium)"));
+                       name = "French (Belgium)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "French (Canada)"));
+                       name = "French (Canada)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "French (Switzerland)"));
+                       name = "French (Switzerland)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "French (Luxembourg)"));
+                       name = "French (Luxembourg)";
                        break;
                case 0x06:
-                       return(copy_lang (lang_out, lang_len, "French (Monaco)"));
+                       name = "French (Monaco)";
                        break;
                }
                break;
        case 0x0d:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Hebrew (Israel)"));
+                       name = "Hebrew (Israel)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Hebrew"));
+                       name = "Hebrew";
                        break;
                }
                break;
        case 0x0e:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Hungarian (Hungary)"));
+                       name = "Hungarian (Hungary)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Hungarian"));
+                       name = "Hungarian";
                        break;
                }
                break;
        case 0x0f:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Icelandic (Iceland)"));
+                       name = "Icelandic (Iceland)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Icelandic"));
+                       name = "Icelandic";
                        break;
                }
                break;
@@ -1417,30 +1366,30 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Italian (Italy)"));
+                       name = "Italian (Italy)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Italian (Switzerland)"));
+                       name = "Italian (Switzerland)";
                        break;
                }
                break;
        case 0x11:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Japanese (Japan)"));
+                       name = "Japanese (Japan)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Japanese"));
+                       name = "Japanese";
                        break;
                }
                break;
        case 0x12:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Korean (Korea)"));
+                       name = "Korean (Korea)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Korean"));
+                       name = "Korean";
                        break;
                }
                break;
@@ -1448,10 +1397,10 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Dutch (Netherlands)"));
+                       name = "Dutch (Netherlands)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Dutch (Belgium)"));
+                       name = "Dutch (Belgium)";
                        break;
                }
                break;
@@ -1459,20 +1408,20 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Norwegian (Bokmal)"));
+                       name = "Norwegian (Bokmal)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Norwegian (Nynorsk)"));
+                       name = "Norwegian (Nynorsk)";
                        break;
                }
                break;
        case 0x15:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Polish (Poland)"));
+                       name = "Polish (Poland)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Polish"));
+                       name = "Polish";
                        break;
                }
                break;
@@ -1480,402 +1429,402 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Portuguese (Brazil)"));
+                       name = "Portuguese (Brazil)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Portuguese (Portugal)"));
+                       name = "Portuguese (Portugal)";
                        break;
                }
                break;
        case 0x17:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Romansh (Switzerland)"));
+                       name = "Romansh (Switzerland)";
                        break;
                }
                break;
        case 0x18:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Romanian (Romania)"));
+                       name = "Romanian (Romania)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Romanian"));
+                       name = "Romanian";
                        break;
                }
                break;
        case 0x19:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Russian (Russia)"));
+                       name = "Russian (Russia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Russian"));
+                       name = "Russian";
                        break;
                }
                break;
        case 0x1a:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Croatian (Croatia)"));
+                       name = "Croatian (Croatia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Croatian"));
+                       name = "Croatian";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Serbian (Latin)"));
+                       name = "Serbian (Latin)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "Serbian (Cyrillic)"));
+                       name = "Serbian (Cyrillic)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "Croatian (Bosnia and Herzegovina)"));
+                       name = "Croatian (Bosnia and Herzegovina)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "Bosnian (Latin, Bosnia and Herzegovina)"));
+                       name = "Bosnian (Latin, Bosnia and Herzegovina)";
                        break;
                case 0x06:
-                       return(copy_lang (lang_out, lang_len, "Serbian (Latin, Bosnia and Herzegovina)"));
+                       name = "Serbian (Latin, Bosnia and Herzegovina)";
                        break;
                case 0x07:
-                       return(copy_lang (lang_out, lang_len, "Serbian (Cyrillic, Bosnia and Herzegovina)"));
+                       name = "Serbian (Cyrillic, Bosnia and Herzegovina)";
                        break;
                case 0x08:
-                       return(copy_lang (lang_out, lang_len, "Bosnian (Cyrillic, Bosnia and Herzegovina)"));
+                       name = "Bosnian (Cyrillic, Bosnia and Herzegovina)";
                        break;
                }
                break;
        case 0x1b:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Slovak (Slovakia)"));
+                       name = "Slovak (Slovakia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Slovak"));
+                       name = "Slovak";
                        break;
                }
                break;
        case 0x1c:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Albanian (Albania)"));
+                       name = "Albanian (Albania)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Albanian"));
+                       name = "Albanian";
                        break;
                }
                break;
        case 0x1d:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Swedish (Sweden)"));
+                       name = "Swedish (Sweden)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Swedish"));
+                       name = "Swedish";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Swedish (Finland)"));
+                       name = "Swedish (Finland)";
                        break;
                }
                break;
        case 0x1e:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Thai (Thailand)"));
+                       name = "Thai (Thailand)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Thai"));
+                       name = "Thai";
                        break;
                }
                break;
        case 0x1f:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Turkish (Turkey)"));
+                       name = "Turkish (Turkey)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Turkish"));
+                       name = "Turkish";
                        break;
                }
                break;
        case 0x20:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Urdu (Islamic Republic of Pakistan)"));
+                       name = "Urdu (Islamic Republic of Pakistan)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Urdu"));
+                       name = "Urdu";
                        break;
                }
                break;
        case 0x21:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Indonesian (Indonesia)"));
+                       name = "Indonesian (Indonesia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Indonesian"));
+                       name = "Indonesian";
                        break;
                }
                break;
        case 0x22:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Ukrainian (Ukraine)"));
+                       name = "Ukrainian (Ukraine)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Ukrainian"));
+                       name = "Ukrainian";
                        break;
                }
                break;
        case 0x23:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Belarusian (Belarus)"));
+                       name = "Belarusian (Belarus)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Belarusian"));
+                       name = "Belarusian";
                        break;
                }
                break;
        case 0x24:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Slovenian (Slovenia)"));
+                       name = "Slovenian (Slovenia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Slovenian"));
+                       name = "Slovenian";
                        break;
                }
                break;
        case 0x25:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Estonian (Estonia)"));
+                       name = "Estonian (Estonia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Estonian"));
+                       name = "Estonian";
                        break;
                }
                break;
        case 0x26:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Latvian (Latvia)"));
+                       name = "Latvian (Latvia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Latvian"));
+                       name = "Latvian";
                        break;
                }
                break;
        case 0x27:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Lithuanian (Lithuania)"));
+                       name = "Lithuanian (Lithuania)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Lithuanian"));
+                       name = "Lithuanian";
                        break;
                }
                break;
        case 0x28:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Tajik (Tajikistan)"));
+                       name = "Tajik (Tajikistan)";
                        break;
                }
                break;
        case 0x29:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Farsi (Iran)"));
+                       name = "Farsi (Iran)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Farsi"));
+                       name = "Farsi";
                        break;
                }
                break;
        case 0x2a:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Vietnamese (Viet Nam)"));
+                       name = "Vietnamese (Viet Nam)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Vietnamese"));
+                       name = "Vietnamese";
                        break;
                }
                break;
        case 0x2b:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Armenian (Armenia)"));
+                       name = "Armenian (Armenia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Armenian"));
+                       name = "Armenian";
                        break;
                }
                break;
        case 0x2c:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Azeri (Latin) (Azerbaijan)"));
+                       name = "Azeri (Latin) (Azerbaijan)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Azeri (Latin)"));
+                       name = "Azeri (Latin)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Azeri (Cyrillic)"));
+                       name = "Azeri (Cyrillic)";
                        break;
                }
                break;
        case 0x2d:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Basque (Spain)"));
+                       name = "Basque (Spain)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Basque"));
+                       name = "Basque";
                        break;
                }
                break;
        case 0x2e:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Upper Sorbian (Germany)"));
+                       name = "Upper Sorbian (Germany)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Lower Sorbian (Germany)"));
+                       name = "Lower Sorbian (Germany)";
                        break;
                }
                break;
        case 0x2f:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "FYRO Macedonian (Former Yugoslav Republic of Macedonia)"));
+                       name = "FYRO Macedonian (Former Yugoslav Republic of Macedonia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "FYRO Macedonian"));
+                       name = "FYRO Macedonian";
                        break;
                }
                break;
        case 0x32:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Tswana (South Africa)"));
+                       name = "Tswana (South Africa)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Tswana"));
+                       name = "Tswana";
                        break;
                }
                break;
        case 0x34:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Xhosa (South Africa)"));
+                       name = "Xhosa (South Africa)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Xhosa"));
+                       name = "Xhosa";
                        break;
                }
                break;
        case 0x35:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Zulu (South Africa)"));
+                       name = "Zulu (South Africa)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Zulu"));
+                       name = "Zulu";
                        break;
                }
                break;
        case 0x36:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Afrikaans (South Africa)"));
+                       name = "Afrikaans (South Africa)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Afrikaans"));
+                       name = "Afrikaans";
                        break;
                }
                break;
        case 0x37:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Georgian (Georgia)"));
+                       name = "Georgian (Georgia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Georgian"));
+                       name = "Georgian";
                        break;
                }
                break;
        case 0x38:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Faroese (Faroe Islands)"));
+                       name = "Faroese (Faroe Islands)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Faroese"));
+                       name = "Faroese";
                        break;
                }
                break;
        case 0x39:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Hindi (India)"));
+                       name = "Hindi (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Hindi"));
+                       name = "Hindi";
                        break;
                }
                break;
        case 0x3a:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Maltese (Malta)"));
+                       name = "Maltese (Malta)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Maltese"));
+                       name = "Maltese";
                        break;
                }
                break;
        case 0x3b:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Sami (Northern) (Norway)"));
+                       name = "Sami (Northern) (Norway)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Sami, Northern (Norway)"));
+                       name = "Sami, Northern (Norway)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Sami, Northern (Sweden)"));
+                       name = "Sami, Northern (Sweden)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "Sami, Northern (Finland)"));
+                       name = "Sami, Northern (Finland)";
                        break;
                case 0x04:
-                       return(copy_lang (lang_out, lang_len, "Sami, Lule (Norway)"));
+                       name = "Sami, Lule (Norway)";
                        break;
                case 0x05:
-                       return(copy_lang (lang_out, lang_len, "Sami, Lule (Sweden)"));
+                       name = "Sami, Lule (Sweden)";
                        break;
                case 0x06:
-                       return(copy_lang (lang_out, lang_len, "Sami, Southern (Norway)"));
+                       name = "Sami, Southern (Norway)";
                        break;
                case 0x07:
-                       return(copy_lang (lang_out, lang_len, "Sami, Southern (Sweden)"));
+                       name = "Sami, Southern (Sweden)";
                        break;
                case 0x08:
-                       return(copy_lang (lang_out, lang_len, "Sami, Skolt (Finland)"));
+                       name = "Sami, Skolt (Finland)";
                        break;
                case 0x09:
-                       return(copy_lang (lang_out, lang_len, "Sami, Inari (Finland)"));
+                       name = "Sami, Inari (Finland)";
                        break;
                }
                break;
        case 0x3c:
                switch(secondary) {
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Irish (Ireland)"));
+                       name = "Irish (Ireland)";
                        break;
                }
                break;
@@ -1883,70 +1832,70 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Malay (Malaysia)"));
+                       name = "Malay (Malaysia)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Malay (Brunei Darussalam)"));
+                       name = "Malay (Brunei Darussalam)";
                        break;
                }
                break;
        case 0x3f:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Kazakh (Kazakhstan)"));
+                       name = "Kazakh (Kazakhstan)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Kazakh"));
+                       name = "Kazakh";
                        break;
                }
                break;
        case 0x40:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Kyrgyz (Kyrgyzstan)"));
+                       name = "Kyrgyz (Kyrgyzstan)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Kyrgyz (Cyrillic)"));
+                       name = "Kyrgyz (Cyrillic)";
                        break;
                }
                break;
        case 0x41:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Swahili (Kenya)"));
+                       name = "Swahili (Kenya)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Swahili"));
+                       name = "Swahili";
                        break;
                }
                break;
        case 0x42:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Turkmen (Turkmenistan)"));
+                       name = "Turkmen (Turkmenistan)";
                        break;
                }
                break;
        case 0x43:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Uzbek (Latin) (Uzbekistan)"));
+                       name = "Uzbek (Latin) (Uzbekistan)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Uzbek (Latin)"));
+                       name = "Uzbek (Latin)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Uzbek (Cyrillic)"));
+                       name = "Uzbek (Cyrillic)";
                        break;
                }
                break;
        case 0x44:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Tatar (Russia)"));
+                       name = "Tatar (Russia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Tatar"));
+                       name = "Tatar";
                        break;
                }
                break;
@@ -1954,57 +1903,57 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Bengali (India)"));
+                       name = "Bengali (India)";
                        break;
                }
                break;
        case 0x46:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Punjabi (India)"));
+                       name = "Punjabi (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Punjabi"));
+                       name = "Punjabi";
                        break;
                }
                break;
        case 0x47:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Gujarati (India)"));
+                       name = "Gujarati (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Gujarati"));
+                       name = "Gujarati";
                        break;
                }
                break;
        case 0x49:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Tamil (India)"));
+                       name = "Tamil (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Tamil"));
+                       name = "Tamil";
                        break;
                }
                break;
        case 0x4a:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Telugu (India)"));
+                       name = "Telugu (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Telugu"));
+                       name = "Telugu";
                        break;
                }
                break;
        case 0x4b:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Kannada (India)"));
+                       name = "Kannada (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Kannada"));
+                       name = "Kannada";
                        break;
                }
                break;
@@ -2012,194 +1961,194 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Malayalam (India)"));
+                       name = "Malayalam (India)";
                        break;
                }
                break;
        case 0x4d:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Assamese (India)"));
+                       name = "Assamese (India)";
                        break;
                }
                break;
        case 0x4e:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Marathi (India)"));
+                       name = "Marathi (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Marathi"));
+                       name = "Marathi";
                        break;
                }
                break;
        case 0x4f:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Sanskrit (India)"));
+                       name = "Sanskrit (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Sanskrit"));
+                       name = "Sanskrit";
                        break;
                }
                break;
        case 0x50:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Mongolian (Mongolia)"));
+                       name = "Mongolian (Mongolia)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Mongolian (Cyrillic)"));
+                       name = "Mongolian (Cyrillic)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Mongolian (PRC)"));
+                       name = "Mongolian (PRC)";
                        break;
                }
                break;
        case 0x51:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Tibetan (PRC)"));
+                       name = "Tibetan (PRC)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Tibetan (Bhutan)"));
+                       name = "Tibetan (Bhutan)";
                        break;
                }
                break;
        case 0x52:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Welsh (United Kingdom)"));
+                       name = "Welsh (United Kingdom)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Welsh"));
+                       name = "Welsh";
                        break;
                }
                break;
        case 0x53:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Khmer (Cambodia)"));
+                       name = "Khmer (Cambodia)";
                        break;
                }
                break;
        case 0x54:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Lao (Lao PDR)"));
+                       name = "Lao (Lao PDR)";
                        break;
                }
                break;
        case 0x56:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Galician (Spain)"));
+                       name = "Galician (Spain)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Galician"));
+                       name = "Galician";
                        break;
                }
                break;
        case 0x57:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Konkani (India)"));
+                       name = "Konkani (India)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Konkani"));
+                       name = "Konkani";
                        break;
                }
                break;
        case 0x5a:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Syriac (Syria)"));
+                       name = "Syriac (Syria)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Syriac"));
+                       name = "Syriac";
                        break;
                }
                break;
        case 0x5b:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Sinhala (Sri Lanka)"));
+                       name = "Sinhala (Sri Lanka)";
                        break;
                }
                break;
        case 0x5d:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Inuktitut (Syllabics, Canada)"));
+                       name = "Inuktitut (Syllabics, Canada)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Inuktitut (Latin, Canada)"));
+                       name = "Inuktitut (Latin, Canada)";
                        break;
                }
                break;
        case 0x5e:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Amharic (Ethiopia)"));
+                       name = "Amharic (Ethiopia)";
                        break;
                }
                break;
        case 0x5f:
                switch(secondary) {
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Tamazight (Algeria, Latin)"));
+                       name = "Tamazight (Algeria, Latin)";
                        break;
                }
                break;
        case 0x61:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Nepali (Nepal)"));
+                       name = "Nepali (Nepal)";
                        break;
                }
                break;
        case 0x62:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Frisian (Netherlands)"));
+                       name = "Frisian (Netherlands)";
                        break;
                }
                break;
        case 0x63:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Pashto (Afghanistan)"));
+                       name = "Pashto (Afghanistan)";
                        break;
                }
                break;
        case 0x64:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Filipino (Philippines)"));
+                       name = "Filipino (Philippines)";
                        break;
                }
                break;
        case 0x65:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Divehi (Maldives)"));
+                       name = "Divehi (Maldives)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Divehi"));
+                       name = "Divehi";
                        break;
                }
                break;
        case 0x68:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Hausa (Nigeria, Latin)"));
+                       name = "Hausa (Nigeria, Latin)";
                        break;
                }
                break;
        case 0x6a:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Yoruba (Nigeria)"));
+                       name = "Yoruba (Nigeria)";
                        break;
                }
                break;
@@ -2207,153 +2156,156 @@ guint32 VerLanguageName (guint32 lang, gunichar2 *lang_out, guint32 lang_len)
                switch(secondary) {
                case 0x00:
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Quechua (Bolivia)"));
+                       name = "Quechua (Bolivia)";
                        break;
                case 0x02:
-                       return(copy_lang (lang_out, lang_len, "Quechua (Ecuador)"));
+                       name = "Quechua (Ecuador)";
                        break;
                case 0x03:
-                       return(copy_lang (lang_out, lang_len, "Quechua (Peru)"));
+                       name = "Quechua (Peru)";
                        break;
                }
                break;
        case 0x6c:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Northern Sotho (South Africa)"));
+                       name = "Northern Sotho (South Africa)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Northern Sotho"));
+                       name = "Northern Sotho";
                        break;
                }
                break;
        case 0x6d:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Bashkir (Russia)"));
+                       name = "Bashkir (Russia)";
                        break;
                }
                break;
        case 0x6e:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Luxembourgish (Luxembourg)"));
+                       name = "Luxembourgish (Luxembourg)";
                        break;
                }
                break;
        case 0x6f:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Greenlandic (Greenland)"));
+                       name = "Greenlandic (Greenland)";
                        break;
                }
                break;
        case 0x78:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Yi (PRC)"));
+                       name = "Yi (PRC)";
                        break;
                }
                break;
        case 0x7a:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Mapudungun (Chile)"));
+                       name = "Mapudungun (Chile)";
                        break;
                }
                break;
        case 0x7c:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Mohawk (Mohawk)"));
+                       name = "Mohawk (Mohawk)";
                        break;
                }
                break;
        case 0x7e:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Breton (France)"));
+                       name = "Breton (France)";
                        break;
                }
                break;
        case 0x7f:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Invariant Language (Invariant Country)"));
+                       name = "Invariant Language (Invariant Country)";
                        break;
                }
                break;
        case 0x80:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Uighur (PRC)"));
+                       name = "Uighur (PRC)";
                        break;
                }
                break;
        case 0x81:
                switch(secondary) {
                case 0x00:
-                       return(copy_lang (lang_out, lang_len, "Maori (New Zealand)"));
+                       name = "Maori (New Zealand)";
                        break;
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Maori"));
+                       name = "Maori";
                        break;
                }
                break;
        case 0x83:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Corsican (France)"));
+                       name = "Corsican (France)";
                        break;
                }
                break;
        case 0x84:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Alsatian (France)"));
+                       name = "Alsatian (France)";
                        break;
                }
                break;
        case 0x85:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Yakut (Russia)"));
+                       name = "Yakut (Russia)";
                        break;
                }
                break;
        case 0x86:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "K'iche (Guatemala)"));
+                       name = "K'iche (Guatemala)";
                        break;
                }
                break;
        case 0x87:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Kinyarwanda (Rwanda)"));
+                       name = "Kinyarwanda (Rwanda)";
                        break;
                }
                break;
        case 0x88:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Wolof (Senegal)"));
+                       name = "Wolof (Senegal)";
                        break;
                }
                break;
        case 0x8c:
                switch(secondary) {
                case 0x01:
-                       return(copy_lang (lang_out, lang_len, "Dari (Afghanistan)"));
+                       name = "Dari (Afghanistan)";
                        break;
                }
                break;
 
        default:
-               return(copy_lang (lang_out, lang_len, "Language Neutral"));
+               name = "Language Neutral";
 
        }
        
-       return(copy_lang (lang_out, lang_len, "Language Neutral"));
+       if (!name)
+               name = "Language Neutral";
+
+       return copy_lang (lang_out, lang_len, name);
 }