=?UTF-8?Q?Gabriel=20Iv=C4=83ncescu=20?=: shell32/autocomplete: Don' t crash when there's another AutoComplete object on the same edit control.
Alexandre Julliard
julliard at winehq.org
Thu Aug 30 16:34:42 CDT 2018
Module: wine
Branch: master
Commit: 9c2217216cbf9a56a5090c848119d84fac9b65ec
URL: https://source.winehq.org/git/wine.git/?a=commit;h=9c2217216cbf9a56a5090c848119d84fac9b65ec
Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date: Mon Aug 27 20:10:46 2018 +0300
shell32/autocomplete: Don't crash when there's another AutoComplete object on the same edit control.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22333
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/shell32/autocomplete.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 99ce23d..cf8da50 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -93,6 +93,14 @@ static inline IAutoCompleteImpl *impl_from_IAutoCompleteDropDown(IAutoCompleteDr
return CONTAINING_RECORD(iface, IAutoCompleteImpl, IAutoCompleteDropDown_iface);
}
+static void destroy_autocomplete_object(IAutoCompleteImpl *ac)
+{
+ ac->hwndEdit = NULL;
+ if (ac->hwndListBox)
+ DestroyWindow(ac->hwndListBox);
+ IAutoComplete2_Release(&ac->IAutoComplete2_iface);
+}
+
/*
Window procedure for autocompletion
*/
@@ -276,10 +284,7 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
RemovePropW(hwnd, autocomplete_propertyW);
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)proc);
- This->hwndEdit = NULL;
- if (This->hwndListBox)
- DestroyWindow(This->hwndListBox);
- IAutoComplete2_Release(&This->IAutoComplete2_iface);
+ destroy_autocomplete_object(This);
return CallWindowProcW(proc, hwnd, uMsg, wParam, lParam);
}
default:
@@ -434,7 +439,7 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
LPCOLESTR pwzsRegKeyPath,
LPCOLESTR pwszQuickComplete)
{
- IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
+ IAutoCompleteImpl *prev, *This = impl_from_IAutoComplete2(iface);
TRACE("(%p)->(%p, %p, %s, %s)\n",
This, hwndEdit, punkACL, debugstr_w(pwzsRegKeyPath), debugstr_w(pwszQuickComplete));
@@ -461,10 +466,22 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
This->initialized = TRUE;
This->hwndEdit = hwndEdit;
- This->wpOrigEditProc = (WNDPROC) SetWindowLongPtrW( hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
- /* Keep at least one reference to the object until the edit window is destroyed. */
+
+ /* If another AutoComplete object was previously assigned to this edit control,
+ release it but keep the same callback on the control, to avoid an infinite
+ recursive loop in ACEditSubclassProc while the property is set to this object */
+ prev = GetPropW(hwndEdit, autocomplete_propertyW);
+ SetPropW(hwndEdit, autocomplete_propertyW, This);
+
+ if (prev && prev->initialized) {
+ This->wpOrigEditProc = prev->wpOrigEditProc;
+ destroy_autocomplete_object(prev);
+ }
+ else
+ This->wpOrigEditProc = (WNDPROC) SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
+
+ /* Keep at least one reference to the object until the edit window is destroyed */
IAutoComplete2_AddRef(&This->IAutoComplete2_iface);
- SetPropW( hwndEdit, autocomplete_propertyW, This );
if (This->options & ACO_AUTOSUGGEST)
create_listbox(This);
More information about the wine-cvs
mailing list