[PATCH 3/7] kernel32: Implement registry mapping in GetPrivateProfileSection().
Zebediah Figura
z.figura12 at gmail.com
Thu Jul 9 22:25:48 CDT 2020
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/kernel32/profile.c | 124 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 122 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c
index 58f1e4ed17b..6525028bb4a 100644
--- a/dlls/kernel32/profile.c
+++ b/dlls/kernel32/profile.c
@@ -1040,6 +1040,29 @@ static HKEY open_file_mapping_key( const WCHAR *filename )
return NULL;
}
+static WCHAR *enum_key( HKEY key, DWORD i )
+{
+ WCHAR *value, *new_value;
+ DWORD max = 256, len;
+ LSTATUS res;
+
+ if (!(value = HeapAlloc( GetProcessHeap(), 0, max * sizeof(WCHAR) ))) return NULL;
+ len = max;
+ while ((res = RegEnumValueW( key, i, value, &len, NULL, NULL, NULL, NULL )) == ERROR_MORE_DATA)
+ {
+ max *= 2;
+ if (!(new_value = HeapReAlloc( GetProcessHeap(), 0, value, max * sizeof(WCHAR) )))
+ {
+ HeapFree( GetProcessHeap(), 0, value );
+ return NULL;
+ }
+ len = max;
+ }
+ if (!res) return value;
+ HeapFree( GetProcessHeap(), 0, value );
+ return NULL;
+}
+
static WCHAR *get_key_value( HKEY key, const WCHAR *value )
{
DWORD size = 0;
@@ -1142,6 +1165,103 @@ static BOOL get_mapped_section_key( const WCHAR *filename, const WCHAR *section,
return TRUE;
}
+static DWORD get_mapped_section( HKEY key, WCHAR *buffer, DWORD size, BOOL return_values )
+{
+ WCHAR *entry, *value;
+ DWORD i, ret = 0;
+
+ for (i = 0; (entry = enum_key( key, i )); ++i)
+ {
+ lstrcpynW( buffer + ret, entry, size - ret - 1 );
+ ret = min( ret + strlenW( entry ) + 1, size - 1 );
+ if (return_values && ret < size - 1 && (value = get_key_value( key, entry )))
+ {
+ buffer[ret - 1] = '=';
+ lstrcpynW( buffer + ret, value, size - ret - 1 );
+ ret = min( ret + strlenW( value ) + 1, size - 1 );
+ HeapFree( GetProcessHeap(), 0, value );
+ }
+ HeapFree( GetProcessHeap(), 0, entry );
+ }
+
+ return ret;
+}
+
+static DWORD get_section( const WCHAR *filename, const WCHAR *section,
+ WCHAR *buffer, DWORD size, BOOL return_values )
+{
+ HKEY key, subkey, section_key;
+ BOOL use_ini = TRUE;
+ DWORD ret = 0;
+ WCHAR *path;
+
+ if ((key = open_file_mapping_key( filename )))
+ {
+ if (!RegOpenKeyExW( key, section, 0, KEY_READ, &subkey ))
+ {
+ WCHAR *entry, *value;
+ HKEY entry_key;
+ DWORD i;
+
+ for (i = 0; (entry = enum_key( subkey, i )); ++i)
+ {
+ if (!(path = get_key_value( subkey, entry )))
+ {
+ HeapFree( GetProcessHeap(), 0, entry );
+ continue;
+ }
+
+ entry_key = open_mapped_key( path, FALSE );
+ HeapFree( GetProcessHeap(), 0, path );
+ if (!entry_key)
+ {
+ HeapFree( GetProcessHeap(), 0, entry );
+ continue;
+ }
+
+ if (entry[0])
+ {
+ if ((value = get_key_value( entry_key, entry )))
+ {
+ lstrcpynW( buffer + ret, entry, size - ret - 1 );
+ ret = min( ret + strlenW( entry ) + 1, size - 1 );
+ if (return_values && ret < size - 1)
+ {
+ buffer[ret - 1] = '=';
+ lstrcpynW( buffer + ret, value, size - ret - 1 );
+ ret = min( ret + strlenW( value ) + 1, size - 1 );
+ }
+ HeapFree( GetProcessHeap(), 0, value );
+ }
+ }
+ else
+ {
+ ret = get_mapped_section( entry_key, buffer, size, return_values );
+ use_ini = FALSE;
+ }
+
+ HeapFree( GetProcessHeap(), 0, entry );
+ RegCloseKey( entry_key );
+ }
+
+ RegCloseKey( subkey );
+ }
+ else if (get_mapped_section_key( filename, section, NULL, FALSE, §ion_key ))
+ {
+ ret = get_mapped_section( section_key, buffer, size, return_values );
+ use_ini = FALSE;
+ RegCloseKey( section_key );
+ }
+
+ RegCloseKey( key );
+ }
+
+ if (use_ini)
+ ret += PROFILE_GetSection( filename, section, buffer + ret, size - ret, return_values );
+
+ return ret;
+}
+
/********************* API functions **********************************/
@@ -1182,7 +1302,7 @@ INT WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
if (!section) return GetPrivateProfileSectionNamesW( buffer, len, filename );
if (!entry)
{
- ret = PROFILE_GetSection( filename, section, buffer, len, FALSE );
+ ret = get_section( filename, section, buffer, len, FALSE );
if (!buffer[0])
{
PROFILE_CopyEntry( buffer, def_val, len );
@@ -1400,7 +1520,7 @@ INT WINAPI GetPrivateProfileSectionW( LPCWSTR section, LPWSTR buffer,
TRACE("(%s, %p, %d, %s)\n", debugstr_w(section), buffer, len, debugstr_w(filename));
- return PROFILE_GetSection( filename, section, buffer, len, TRUE );
+ return get_section( filename, section, buffer, len, TRUE );
}
/***********************************************************************
--
2.27.0
More information about the wine-devel
mailing list