mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 16:32:18 +01:00 
			
		
		
		
	GWin32RegistryKey: add MUI capabilities to get_value()
An extra argument to g_win32_registry_key_get_value_w() and g_win32_registry_key_get_value() indicates that RegLoadMUIStringW() should be used instead of RegQueryValueExW(). It only works on strings, and automatically resolves resource strings (the ones that start with "@"). The extra argument is needed to find resource DLLs that are only specified by their relative name.
This commit is contained in:
		| @@ -601,6 +601,7 @@ read_handler_icon (GWin32RegistryKey  *proxy_key, | ||||
|           gchar *default_value; | ||||
|  | ||||
|           if (g_win32_registry_key_get_value (icon_key, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               "", | ||||
|                                               &default_type, | ||||
| @@ -763,6 +764,7 @@ follow_class_chain_to_handler (const gunichar2    *program_id, | ||||
|   if (key != NULL) | ||||
|     { | ||||
|       got_value = g_win32_registry_key_get_value_w (key, | ||||
|                                                     NULL, | ||||
|                                                     TRUE, | ||||
|                                                     L"", | ||||
|                                                     &val_type, | ||||
| @@ -799,6 +801,7 @@ follow_class_chain_to_handler (const gunichar2    *program_id, | ||||
|     return FALSE; | ||||
|  | ||||
|   got_value = g_win32_registry_key_get_value_w (key, | ||||
|                                                 NULL, | ||||
|                                                 TRUE, | ||||
|                                                 L"", | ||||
|                                                 &val_type, | ||||
| @@ -826,6 +829,7 @@ follow_class_chain_to_handler (const gunichar2    *program_id, | ||||
|     } | ||||
|  | ||||
|   got_value = g_win32_registry_key_get_value_w (key, | ||||
|                                                 NULL, | ||||
|                                                 TRUE, | ||||
|                                                 L"", | ||||
|                                                 &val_type, | ||||
| @@ -890,6 +894,7 @@ get_url_association (const gunichar2 *schema) | ||||
|   schema_rec = g_hash_table_lookup (urls, schema_folded); | ||||
|  | ||||
|   if (!g_win32_registry_key_get_value_w (user_choice, | ||||
|                                          NULL, | ||||
|                                          TRUE, | ||||
|                                          L"Progid", | ||||
|                                          &val_type, | ||||
| @@ -1054,6 +1059,7 @@ get_file_ext (const gunichar2 *ext) | ||||
|   if (user_choice != NULL) | ||||
|     { | ||||
|       if (g_win32_registry_key_get_value_w (user_choice, | ||||
|                                             NULL, | ||||
|                                             TRUE, | ||||
|                                             L"Progid", | ||||
|                                             &val_type, | ||||
| @@ -1336,6 +1342,7 @@ collect_capable_apps_from_clients (GPtrArray *capable_apps, | ||||
|         continue; | ||||
|  | ||||
|       if (g_win32_registry_key_get_value_w (system_client_type, | ||||
|                                             NULL, | ||||
|                                             TRUE, | ||||
|                                             L"", | ||||
|                                             &default_type, | ||||
| @@ -1591,6 +1598,7 @@ read_capable_app (gunichar2 *input_app_key_path, gboolean user_specific, gboolea | ||||
|   shell_open_command = NULL; | ||||
|  | ||||
|   success = g_win32_registry_key_get_value_w (shell_open_command_key, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               L"", | ||||
|                                               &vtype, | ||||
| @@ -1655,6 +1663,7 @@ read_capable_app (gunichar2 *input_app_key_path, gboolean user_specific, gboolea | ||||
|  | ||||
|   fallback_friendly_name = NULL; | ||||
|   success = g_win32_registry_key_get_value_w (appkey, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               L"", | ||||
|                                               &vtype, | ||||
| @@ -1678,6 +1687,7 @@ read_capable_app (gunichar2 *input_app_key_path, gboolean user_specific, gboolea | ||||
|  | ||||
|   friendly_name = NULL; | ||||
|   success = g_win32_registry_key_get_value_w (capabilities, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               L"LocalizedString", | ||||
|                                               &vtype, | ||||
| @@ -1703,6 +1713,7 @@ read_capable_app (gunichar2 *input_app_key_path, gboolean user_specific, gboolea | ||||
|  | ||||
|   description = NULL; | ||||
|   success = g_win32_registry_key_get_value_w (capabilities, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               L"ApplicationDescription", | ||||
|                                               &vtype, | ||||
| @@ -1731,6 +1742,7 @@ read_capable_app (gunichar2 *input_app_key_path, gboolean user_specific, gboolea | ||||
|   if (default_icon_key != NULL) | ||||
|     { | ||||
|       success = g_win32_registry_key_get_value_w (default_icon_key, | ||||
|                                                   NULL, | ||||
|                                                   TRUE, | ||||
|                                                   L"", | ||||
|                                                   &vtype, | ||||
| @@ -1747,6 +1759,7 @@ read_capable_app (gunichar2 *input_app_key_path, gboolean user_specific, gboolea | ||||
|   if (icon_source == NULL) | ||||
|     { | ||||
|       success = g_win32_registry_key_get_value_w (capabilities, | ||||
|                                                   NULL, | ||||
|                                                   TRUE, | ||||
|                                                   L"ApplicationIcon", | ||||
|                                                   &vtype, | ||||
| @@ -1767,6 +1780,7 @@ read_capable_app (gunichar2 *input_app_key_path, gboolean user_specific, gboolea | ||||
|  | ||||
|   narrow_application_name = NULL; | ||||
|   success = g_win32_registry_key_get_value_w (capabilities, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               L"ApplicationName", | ||||
|                                               &vtype, | ||||
| @@ -2218,6 +2232,7 @@ read_exeapps (void) | ||||
|       if (shell_open_command_key != NULL) | ||||
|         { | ||||
|           success = g_win32_registry_key_get_value_w (shell_open_command_key, | ||||
|                                                       NULL, | ||||
|                                                       TRUE, | ||||
|                                                       L"", | ||||
|                                                       &vtype, | ||||
| @@ -2237,6 +2252,7 @@ read_exeapps (void) | ||||
|  | ||||
|       friendly_app_name = NULL; | ||||
|       success = g_win32_registry_key_get_value_w (incapable_app, | ||||
|                                                   NULL, | ||||
|                                                   TRUE, | ||||
|                                                   L"FriendlyAppName", | ||||
|                                                   &vtype, | ||||
| @@ -2251,6 +2267,7 @@ read_exeapps (void) | ||||
|  | ||||
|       no_open_with = FALSE; | ||||
|       success = g_win32_registry_key_get_value_w (incapable_app, | ||||
|                                                   NULL, | ||||
|                                                   TRUE, | ||||
|                                                   L"NoOpenWith", | ||||
|                                                   &vtype, | ||||
| @@ -2272,6 +2289,7 @@ read_exeapps (void) | ||||
|       { | ||||
|         success = | ||||
|             g_win32_registry_key_get_value_w (default_icon_key, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               L"", | ||||
|                                               &vtype, | ||||
| @@ -2590,6 +2608,7 @@ read_class_url (GWin32RegistryKey *classes_root, | ||||
|     return; | ||||
|  | ||||
|   success = g_win32_registry_key_get_value_w (class_key, | ||||
|                                               NULL, | ||||
|                                               TRUE, | ||||
|                                               L"URL Protocol", | ||||
|                                               &vtype, | ||||
| @@ -3980,6 +3999,7 @@ get_appath_for_exe (gunichar2 *exe_basename) | ||||
|     return NULL; | ||||
|  | ||||
|   got_value = g_win32_registry_key_get_value_w (apppath_key, | ||||
|                                                 NULL, | ||||
|                                                 TRUE, | ||||
|                                                 L"Path", | ||||
|                                                 &val_type, | ||||
|   | ||||
| @@ -1838,9 +1838,117 @@ g_win32_registry_key_get_path_w (GWin32RegistryKey *key) | ||||
|   return key->priv->absolute_path_w; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_win32_registry_get_os_dirs_w: | ||||
|  * | ||||
|  * Returns a list of directories for DLL lookups. | ||||
|  * Can be used with g_win32_registry_key_get_value_w(). | ||||
|  * | ||||
|  * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of UTF-16 strings. | ||||
|  * | ||||
|  * Since: 2.66 | ||||
|  */ | ||||
| const gunichar2 * const * | ||||
| g_win32_registry_get_os_dirs_w (void) | ||||
| { | ||||
|   static gunichar2 **mui_os_dirs = NULL; | ||||
|  | ||||
|   if (g_once_init_enter (&mui_os_dirs)) | ||||
|     { | ||||
|       gunichar2 **new_mui_os_dirs; | ||||
|       gunichar2 *system32 = NULL; | ||||
|       gunichar2 *syswow64 = NULL; | ||||
|       UINT buffer_size; | ||||
|       gsize array_index = 0; | ||||
|  | ||||
|       buffer_size = GetSystemWow64DirectoryW (NULL, 0); | ||||
|  | ||||
|       if (buffer_size > 0) | ||||
|         { | ||||
|           UINT copied; | ||||
|           syswow64 = g_malloc (buffer_size * sizeof (gunichar2)); | ||||
|           copied = GetSystemWow64DirectoryW (syswow64, buffer_size); | ||||
|           if (copied <= 0) | ||||
|             g_clear_pointer (&syswow64, g_free); | ||||
|         } | ||||
|  | ||||
|       buffer_size = GetSystemDirectoryW (NULL, 0); | ||||
|  | ||||
|       if (buffer_size > 0) | ||||
|         { | ||||
|           UINT copied; | ||||
|           system32 = g_malloc (buffer_size * sizeof (gunichar2)); | ||||
|           copied = GetSystemDirectoryW (system32, buffer_size); | ||||
|           if (copied <= 0) | ||||
|             g_clear_pointer (&system32, g_free); | ||||
|         } | ||||
|  | ||||
|       new_mui_os_dirs = g_new0 (gunichar2 *, 3); | ||||
|  | ||||
|       if (system32 != NULL) | ||||
|         new_mui_os_dirs[array_index++] = system32; | ||||
|  | ||||
|       if (syswow64 != NULL) | ||||
|         new_mui_os_dirs[array_index++] = syswow64; | ||||
|  | ||||
|       new_mui_os_dirs[array_index++] = NULL; | ||||
|  | ||||
|       g_once_init_leave (&mui_os_dirs, new_mui_os_dirs); | ||||
|     } | ||||
|  | ||||
|   return (const gunichar2 * const *) mui_os_dirs; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_win32_registry_get_os_dirs: | ||||
|  * | ||||
|  * Returns a list of directories for DLL lookups. | ||||
|  * Can be used with g_win32_registry_key_get_value(). | ||||
|  * | ||||
|  * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of UTF-8 strings. | ||||
|  * | ||||
|  * Since: 2.66 | ||||
|  */ | ||||
| const gchar * const * | ||||
| g_win32_registry_get_os_dirs (void) | ||||
| { | ||||
|   static gchar **mui_os_dirs = NULL; | ||||
|  | ||||
|   if (g_once_init_enter (&mui_os_dirs)) | ||||
|     { | ||||
|       gchar **new_mui_os_dirs; | ||||
|       gsize array_index; | ||||
|       gsize new_array_index; | ||||
|       const gunichar2 * const *mui_os_dirs_utf16 = g_win32_registry_get_os_dirs_w (); | ||||
|  | ||||
|       for (array_index = 0; mui_os_dirs_utf16[array_index] != NULL; array_index++) | ||||
|         ; | ||||
|  | ||||
|       new_mui_os_dirs = g_new0 (gchar *, array_index + 1); | ||||
|  | ||||
|       for (array_index = 0, new_array_index = 0; | ||||
|            mui_os_dirs_utf16[array_index] != NULL; | ||||
|            array_index++) | ||||
|         { | ||||
|           new_mui_os_dirs[new_array_index] = g_utf16_to_utf8 (mui_os_dirs_utf16[array_index], | ||||
|                                                               -1, NULL, NULL, NULL); | ||||
|           if (new_mui_os_dirs[new_array_index] != NULL) | ||||
|             new_array_index += 1; | ||||
|         } | ||||
|  | ||||
|       g_once_init_leave (&mui_os_dirs, new_mui_os_dirs); | ||||
|     } | ||||
|  | ||||
|   return (const gchar * const *) mui_os_dirs; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_win32_registry_key_get_value: | ||||
|  * @key: (in) (transfer none): a #GWin32RegistryKey | ||||
|  * @mui_dll_dirs: (in) (transfer none) (array zero-terminated=1) (optional): a %NULL-terminated | ||||
|  *     array of directory names where the OS | ||||
|  *     should look for a DLL indicated in a MUI string, if the | ||||
|  *     DLL path in the string is not absolute | ||||
|  * @auto_expand: (in) %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR | ||||
|  *     to G_WIN32_REGISTRY_VALUE_STR. | ||||
|  * @value_name: (in) (transfer none): name of the value to get (in UTF-8). | ||||
| @@ -1854,12 +1962,32 @@ g_win32_registry_key_get_path_w (GWin32RegistryKey *key) | ||||
|  * Get data from a value of a key. String data is guaranteed to be | ||||
|  * appropriately terminated and will be in UTF-8. | ||||
|  * | ||||
|  * When not %NULL, @mui_dll_dirs indicates that `RegLoadMUIStringW()` API | ||||
|  * should be used instead of the usual `RegQueryValueExW()`. This implies | ||||
|  * that the value being queried is of type `REG_SZ` or `REG_EXPAND_SZ` (if it is not, the function | ||||
|  * falls back to `RegQueryValueExW()`), and that this string must undergo special processing | ||||
|  * (see [`SHLoadIndirectString()` documentation](https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring) for an explanation on what | ||||
|  * kinds of strings are processed) to get the result. | ||||
|  * | ||||
|  * If no specific MUI DLL directories need to be used, pass | ||||
|  * the return value of g_win32_registry_get_os_dirs() as @mui_dll_dirs | ||||
|  * (as an bonus, the value from g_win32_registry_get_os_dirs() | ||||
|  * does not add any extra UTF8->UTF16 conversion overhead). | ||||
|  * | ||||
|  * @auto_expand works with @mui_dll_dirs, but only affects the processed | ||||
|  * string, making it somewhat useless. The unprocessed string is always expanded | ||||
|  * internally, if its type is `REG_EXPAND_SZ` - there is no need to enable | ||||
|  * @auto_expand for this to work. | ||||
|  * | ||||
|  * The API for this function changed in GLib 2.66 to add the @mui_dll_dirs argument. | ||||
|  * | ||||
|  * Returns: %TRUE on success, %FALSE on failure. | ||||
|  * | ||||
|  * Since: 2.46 | ||||
|  * Since: 2.66 | ||||
|  **/ | ||||
| gboolean | ||||
| g_win32_registry_key_get_value (GWin32RegistryKey        *key, | ||||
|                                 const gchar * const      *mui_dll_dirs, | ||||
|                                 gboolean                  auto_expand, | ||||
|                                 const gchar              *value_name, | ||||
|                                 GWin32RegistryValueType  *value_type, | ||||
| @@ -1874,6 +2002,9 @@ g_win32_registry_key_get_value (GWin32RegistryKey        *key, | ||||
|   gchar *value_data_u8; | ||||
|   gsize value_data_u8_len; | ||||
|   gboolean result; | ||||
|   gsize mui_dll_dirs_count; | ||||
|   gunichar2 **mui_dll_dirs_utf16; | ||||
|   const gchar * const *mui_os_dirs; | ||||
|  | ||||
|   g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE); | ||||
|   g_return_val_if_fail (value_name != NULL, FALSE); | ||||
| @@ -1889,7 +2020,39 @@ g_win32_registry_key_get_value (GWin32RegistryKey        *key, | ||||
|   if (value_name_w == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   mui_dll_dirs_utf16 = NULL; | ||||
|   mui_os_dirs = g_win32_registry_get_os_dirs (); | ||||
|  | ||||
|   if (mui_dll_dirs != NULL && | ||||
|       mui_dll_dirs != mui_os_dirs) | ||||
|     { | ||||
|       gsize mui_dll_dirs_index; | ||||
|  | ||||
|       mui_dll_dirs_count = g_strv_length ((gchar **) mui_dll_dirs); | ||||
|  | ||||
|       if (mui_dll_dirs_count > 0) | ||||
|         { | ||||
|           mui_dll_dirs_utf16 = g_new0 (gunichar2 *, mui_dll_dirs_count + 1); | ||||
|  | ||||
|           for (mui_dll_dirs_count = 0, mui_dll_dirs_index = 0; | ||||
|                mui_dll_dirs[mui_dll_dirs_index] != NULL; | ||||
|                mui_dll_dirs_index++) | ||||
|             { | ||||
|               mui_dll_dirs_utf16[mui_dll_dirs_count] = g_utf8_to_utf16 (mui_dll_dirs[mui_dll_dirs_index], | ||||
|                                                                         -1, NULL, NULL, NULL); | ||||
|               if (mui_dll_dirs_utf16[mui_dll_dirs_count] != NULL) | ||||
|                 mui_dll_dirs_count += 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   else if (mui_dll_dirs != NULL && | ||||
|            mui_dll_dirs == mui_os_dirs) | ||||
|     { | ||||
|       mui_dll_dirs_utf16 = (gunichar2 **) g_win32_registry_get_os_dirs_w (); | ||||
|     } | ||||
|  | ||||
|   result = g_win32_registry_key_get_value_w (key, | ||||
|                                              (const gunichar2 * const *) mui_dll_dirs_utf16, | ||||
|                                              auto_expand, | ||||
|                                              value_name_w, | ||||
|                                              &value_type_g, | ||||
| @@ -1898,6 +2061,14 @@ g_win32_registry_key_get_value (GWin32RegistryKey        *key, | ||||
|                                              error); | ||||
|  | ||||
|   g_free (value_name_w); | ||||
|   if (mui_dll_dirs_utf16 != NULL && | ||||
|       mui_dll_dirs != mui_os_dirs) | ||||
|     { | ||||
|       gsize array_index; | ||||
|       for (array_index = 0; mui_dll_dirs_utf16[array_index] != NULL; array_index++) | ||||
|         g_free (mui_dll_dirs_utf16[array_index]); | ||||
|       g_free (mui_dll_dirs_utf16); | ||||
|     } | ||||
|  | ||||
|   if (!result) | ||||
|     return FALSE; | ||||
| @@ -1944,9 +2115,98 @@ g_win32_registry_key_get_value (GWin32RegistryKey        *key, | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| /* A wrapper that calls either RegQueryValueExW() or | ||||
|  * RegLoadMUIStringW() depending on the value of the | ||||
|  * last argument. | ||||
|  * Apart from the extra argument, the function behaves | ||||
|  * just like RegQueryValueExW(), with a few caveats. | ||||
|  */ | ||||
| static LSTATUS | ||||
| MuiRegQueryValueExW (HKEY                     hKey, | ||||
|                      LPCWSTR                  lpValueName, | ||||
|                      LPDWORD                  lpReserved, | ||||
|                      LPDWORD                  lpType, | ||||
|                      LPBYTE                   lpData, | ||||
|                      LPDWORD                  lpcbData, | ||||
|                      const gunichar2 * const *mui_dll_dirs) | ||||
| { | ||||
|   gsize dir_index; | ||||
|   LSTATUS result = ERROR_PATH_NOT_FOUND; | ||||
|   DWORD bufsize; | ||||
|   DWORD data_size; | ||||
|   PVOID old_value; | ||||
|  | ||||
|   if (mui_dll_dirs == NULL) | ||||
|     return RegQueryValueExW (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); | ||||
|  | ||||
|   bufsize = 0; | ||||
|  | ||||
|   if (lpcbData != NULL) | ||||
|     bufsize = *lpcbData; | ||||
|  | ||||
|   if (mui_dll_dirs[0] != NULL) | ||||
|     { | ||||
|       /* Optimization: check that the value actually exists, | ||||
|        * before we start trying different mui dll dirs | ||||
|        */ | ||||
|       result = RegQueryValueExW (hKey, lpValueName, NULL, NULL, NULL, 0); | ||||
|  | ||||
|       if (result == ERROR_FILE_NOT_FOUND) | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|   Wow64DisableWow64FsRedirection (&old_value); | ||||
|  | ||||
|   /* Try with NULL dir first */ | ||||
|   result = RegLoadMUIStringW (hKey, | ||||
|                               lpValueName, | ||||
|                               (wchar_t *) lpData, | ||||
|                               bufsize, | ||||
|                               &data_size, | ||||
|                               0, | ||||
|                               NULL); | ||||
|  | ||||
|   /* Not a MUI value, load normally */ | ||||
|   if (result == ERROR_INVALID_DATA) | ||||
|     { | ||||
|       Wow64RevertWow64FsRedirection (old_value); | ||||
|  | ||||
|       return RegQueryValueExW (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); | ||||
|     } | ||||
|  | ||||
|   for (dir_index = 0; | ||||
|        result == ERROR_FILE_NOT_FOUND && | ||||
|        mui_dll_dirs[dir_index] != NULL; | ||||
|        dir_index++) | ||||
|     result = RegLoadMUIStringW (hKey, | ||||
|                                 lpValueName, | ||||
|                                 (wchar_t *) lpData, | ||||
|                                 bufsize, | ||||
|                                 &data_size, | ||||
|                                 0, | ||||
|                                 mui_dll_dirs[dir_index]); | ||||
|  | ||||
|   Wow64RevertWow64FsRedirection (old_value); | ||||
|  | ||||
|   if (lpcbData != NULL && | ||||
|       result == ERROR_MORE_DATA) | ||||
|     *lpcbData = data_size; | ||||
|  | ||||
|   if (lpType != NULL && | ||||
|       result != ERROR_INVALID_DATA && | ||||
|       result != ERROR_FILE_NOT_FOUND) | ||||
|     *lpType = REG_SZ; | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_win32_registry_key_get_value_w: | ||||
|  * @key: (in) (transfer none): a #GWin32RegistryKey | ||||
|  * @mui_dll_dirs: (in) (transfer none) (array zero-terminated=1) (optional): a %NULL-terminated | ||||
|  *     array of directory names where the OS | ||||
|  *     should look for a DLL indicated in a MUI string, if the | ||||
|  *     DLL path in the string is not absolute | ||||
|  * @auto_expand: (in) %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR | ||||
|  *     to G_WIN32_REGISTRY_VALUE_STR. | ||||
|  * @value_name: (in) (transfer none): name of the value to get (in UTF-16). | ||||
| @@ -1957,8 +2217,6 @@ g_win32_registry_key_get_value (GWin32RegistryKey        *key, | ||||
|  *   by @value_data. | ||||
|  * @error: (nullable): a pointer to %NULL #GError, or %NULL | ||||
|  * | ||||
|  * Get data from a value of a key. | ||||
|  * | ||||
|  * Get data from a value of a key. String data is guaranteed to be | ||||
|  * appropriately terminated and will be in UTF-16. | ||||
|  * | ||||
| @@ -1968,12 +2226,30 @@ g_win32_registry_key_get_value (GWin32RegistryKey        *key, | ||||
|  * termination cannot be checked and fixed unless the data is retreived | ||||
|  * too. | ||||
|  * | ||||
|  * When not %NULL, @mui_dll_dirs indicates that `RegLoadMUIStringW()` API | ||||
|  * should be used instead of the usual `RegQueryValueExW()`. This implies | ||||
|  * that the value being queried is of type `REG_SZ` or `REG_EXPAND_SZ` (if it is not, the function | ||||
|  * falls back to `RegQueryValueExW()`), and that this string must undergo special processing | ||||
|  * (see [`SHLoadIndirectString()` documentation](https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring) for an explanation on what | ||||
|  * kinds of strings are processed) to get the result. | ||||
|  * | ||||
|  * If no specific MUI DLL directories need to be used, pass | ||||
|  * the return value of g_win32_registry_get_os_dirs_w() as @mui_dll_dirs. | ||||
|  * | ||||
|  * @auto_expand works with @mui_dll_dirs, but only affects the processed | ||||
|  * string, making it somewhat useless. The unprocessed string is always expanded | ||||
|  * internally, if its type is `REG_EXPAND_SZ` - there is no need to enable | ||||
|  * @auto_expand for this to work. | ||||
|  * | ||||
|  * The API for this function changed in GLib 2.66 to add the @mui_dll_dirs argument. | ||||
|  * | ||||
|  * Returns: %TRUE on success, %FALSE on failure. | ||||
|  * | ||||
|  * Since: 2.46 | ||||
|  * Since: 2.66 | ||||
|  **/ | ||||
| gboolean | ||||
| g_win32_registry_key_get_value_w (GWin32RegistryKey        *key, | ||||
|                                   const gunichar2 * const  *mui_dll_dirs, | ||||
|                                   gboolean                  auto_expand, | ||||
|                                   const gunichar2          *value_name, | ||||
|                                   GWin32RegistryValueType  *value_type, | ||||
| @@ -2000,12 +2276,13 @@ g_win32_registry_key_get_value_w (GWin32RegistryKey        *key, | ||||
|                         value_data_size != NULL, FALSE); | ||||
|  | ||||
|   req_value_data_size = 0; | ||||
|   status = RegQueryValueExW (key->priv->handle, | ||||
|                              value_name, | ||||
|                              NULL, | ||||
|                              &value_type_w, | ||||
|                              NULL, | ||||
|                              &req_value_data_size); | ||||
|   status = MuiRegQueryValueExW (key->priv->handle, | ||||
|                                 value_name, | ||||
|                                 NULL, | ||||
|                                 &value_type_w, | ||||
|                                 NULL, | ||||
|                                 &req_value_data_size, | ||||
|                                 mui_dll_dirs); | ||||
|  | ||||
|   if (status != ERROR_MORE_DATA && status != ERROR_SUCCESS) | ||||
|     { | ||||
| @@ -2032,12 +2309,13 @@ g_win32_registry_key_get_value_w (GWin32RegistryKey        *key, | ||||
|  | ||||
|   req_value_data = g_malloc (req_value_data_size + sizeof (gunichar2) * 2); | ||||
|   req_value_data_size2 = req_value_data_size; | ||||
|   status = RegQueryValueExW (key->priv->handle, | ||||
|                              value_name, | ||||
|                              NULL, | ||||
|                              &value_type_w2, | ||||
|                              (gpointer) req_value_data, | ||||
|                              &req_value_data_size2); | ||||
|   status = MuiRegQueryValueExW (key->priv->handle, | ||||
|                                 value_name, | ||||
|                                 NULL, | ||||
|                                 &value_type_w2, | ||||
|                                 (gpointer) req_value_data, | ||||
|                                 &req_value_data_size2, | ||||
|                                 mui_dll_dirs); | ||||
|  | ||||
|   if (status != ERROR_SUCCESS) | ||||
|     { | ||||
|   | ||||
| @@ -239,8 +239,9 @@ gboolean         g_win32_registry_value_iter_get_data_w      (GWin32RegistryValu | ||||
|                                                               gsize                           *value_data_size, | ||||
|                                                               GError                         **error); | ||||
|  | ||||
| GLIB_AVAILABLE_IN_2_46 | ||||
| GLIB_AVAILABLE_IN_2_66 | ||||
| gboolean         g_win32_registry_key_get_value              (GWin32RegistryKey               *key, | ||||
|                                                               const gchar * const             *mui_dll_dirs, | ||||
|                                                               gboolean                         auto_expand, | ||||
|                                                               const gchar                     *value_name, | ||||
|                                                               GWin32RegistryValueType         *value_type, | ||||
| @@ -248,8 +249,9 @@ gboolean         g_win32_registry_key_get_value              (GWin32RegistryKey | ||||
|                                                               gsize                           *value_data_size, | ||||
|                                                               GError                         **error); | ||||
|  | ||||
| GLIB_AVAILABLE_IN_2_46 | ||||
| GLIB_AVAILABLE_IN_2_66 | ||||
| gboolean         g_win32_registry_key_get_value_w            (GWin32RegistryKey               *key, | ||||
|                                                               const gunichar2 * const         *mui_dll_dirs, | ||||
|                                                               gboolean                         auto_expand, | ||||
|                                                               const gunichar2                 *value_name, | ||||
|                                                               GWin32RegistryValueType         *value_type, | ||||
| @@ -276,6 +278,12 @@ gboolean         g_win32_registry_key_has_changed            (GWin32RegistryKey | ||||
| GLIB_AVAILABLE_IN_2_46 | ||||
| void             g_win32_registry_key_erase_change_indicator (GWin32RegistryKey               *key); | ||||
|  | ||||
| GLIB_AVAILABLE_IN_2_66 | ||||
| const gunichar2 * const *g_win32_registry_get_os_dirs_w (void); | ||||
|  | ||||
| GLIB_AVAILABLE_IN_2_66 | ||||
| const gchar * const     *g_win32_registry_get_os_dirs   (void); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* G_PLATFORM_WIN32 */ | ||||
|   | ||||
							
								
								
									
										10
									
								
								glib.supp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								glib.supp
									
									
									
									
									
								
							| @@ -887,6 +887,16 @@ | ||||
| 	fun:g_dbus_error_quark | ||||
| } | ||||
|  | ||||
| # g_win32_registry_get_os_dirs_w*() caches an array of strings that is allocated only once. | ||||
| { | ||||
| 	g_win32_registry_get_os_dirs | ||||
| 	Memcheck:Leak | ||||
| 	match-leak-kinds:reachable,definite | ||||
| 	fun:malloc | ||||
| 	... | ||||
| 	fun:g_win32_registry_get_os_dirs* | ||||
| } | ||||
|  | ||||
| # Thread-private data allocated once per thread | ||||
| { | ||||
| 	g_private_set_alloc0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user