From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 110 ++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 26 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index eee1da3d71c..963d48c9ee4 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -587,46 +587,104 @@ static HKEY open_hkcu_key( const char *name ) return reg_open_key( hkcu, bufferW, asciiz_to_unicode( bufferW, name ) - sizeof(WCHAR) ); }
-static NTSTATUS query_reg_value( HKEY hkey, const WCHAR *name, KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size ) +static ULONG query_reg_value( HKEY hkey, const WCHAR *name, KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size ) { unsigned int name_size = name ? lstrlenW( name ) * sizeof(WCHAR) : 0; UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name };
- return NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, info, size, &size ); + if (NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, + info, size, &size )) + return 0; + + return size - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); }
-/* build the extension string by filtering out the disabled extensions */ -static BOOL filter_extensions( TEB * teb, const char *extensions, GLubyte **exts_list, GLuint **disabled_exts ) +static ULONG query_reg_ascii_value( HKEY hkey, const char *name, KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size ) { - static const char *disabled; + WCHAR nameW[64]; + asciiz_to_unicode( nameW, name ); + return query_reg_value( hkey, nameW, info, size ); +}
- if (!disabled) +static DWORD get_ascii_config_key( HKEY defkey, HKEY appkey, const char *name, + char *buffer, DWORD size ) +{ + char buf[offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data[4096])]; + KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buf; + + if (appkey && query_reg_ascii_value( appkey, name, info, sizeof(buf) )) { - char *str = NULL; - HKEY hkey; + size = min( info->DataLength, size - sizeof(WCHAR) ) / sizeof(WCHAR); + unicode_to_ascii( buffer, (WCHAR *)info->Data, size ); + buffer[size] = 0; + return 0; + }
- /* @@ Wine registry key: HKCU\Software\Wine\OpenGL */ - if ((hkey = open_hkcu_key( "Software\Wine\OpenGL" ))) - { - char buffer[4096]; - KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - static WCHAR disabled_extensionsW[] = {'D','i','s','a','b','l','e','d','E','x','t','e','n','s','i','o','n','s',0}; + if (defkey && query_reg_ascii_value( defkey, name, info, sizeof(buf) )) + { + size = min( info->DataLength, size - sizeof(WCHAR) ) / sizeof(WCHAR); + unicode_to_ascii( buffer, (WCHAR *)info->Data, size ); + buffer[size] = 0; + return 0; + }
- if (!query_reg_value( hkey, disabled_extensionsW, value, sizeof(buffer) )) - { - ULONG len = value->DataLength / sizeof(WCHAR); + return ERROR_FILE_NOT_FOUND; +}
- unicode_to_ascii( buffer, (WCHAR *)value->Data, len ); - buffer[len] = 0; - str = strdup( buffer ); - } - NtClose( hkey ); - } - if (str) +static char *query_opengl_option( const char *name ) +{ + WCHAR bufferW[MAX_PATH + 16], *p, *appname; + HKEY defkey, appkey = 0; + char buffer[4096]; + char *str = NULL; + DWORD len; + + /* @@ Wine registry key: HKCU\Software\Wine\OpenGL */ + defkey = open_hkcu_key( "Software\Wine\OpenGL" ); + + /* open the app-specific key */ + appname = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer; + if ((p = wcsrchr( appname, '/' ))) appname = p + 1; + if ((p = wcsrchr( appname, '\' ))) appname = p + 1; + len = lstrlenW( appname ); + + if (len && len < MAX_PATH) + { + HKEY tmpkey; + int i; + + for (i = 0; appname[i]; i++) bufferW[i] = RtlDowncaseUnicodeChar( appname[i] ); + bufferW[i] = 0; + appname = bufferW; + + /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\OpenGL */ + if ((tmpkey = open_hkcu_key( "Software\Wine\AppDefaults" ))) { - if (InterlockedCompareExchangePointer( (void **)&disabled, str, NULL )) free( str ); + static const WCHAR openglW[] = {'\','O','p','e','n','G','L',0}; + memcpy( appname + i, openglW, sizeof(openglW) ); + appkey = reg_open_key( tmpkey, appname, lstrlenW( appname ) * sizeof(WCHAR) ); + NtClose( tmpkey ); } - else disabled = ""; + } + + if (!get_ascii_config_key( defkey, appkey, name, buffer, sizeof(buffer) )) + str = strdup( buffer ); + + if (appkey) NtClose( appkey ); + if (defkey) NtClose( defkey ); + return str; +} + +/* build the extension string by filtering out the disabled extensions */ +static BOOL filter_extensions( TEB * teb, const char *extensions, GLubyte **exts_list, GLuint **disabled_exts ) +{ + static const char *disabled; + char *str; + + if (!disabled) + { + if (!(str = query_opengl_option( "DisabledExtensions" ))) disabled = ""; + else if (InterlockedCompareExchangePointer( (void **)&disabled, str, NULL )) free( str ); }
if (extensions && !*exts_list) *exts_list = filter_extensions_list( extensions, disabled );