From: Detlef Riekenberg Subject: [PATCH 1/3] user32: The app own the text buffer memory after a EM_GETHANDLE [bug 4742] Message-Id: <1367531419-13682-1-git-send-email-wine.dev@web.de> Date: Thu, 2 May 2013 23:50:17 +0200 The newtestbot failures on win8 are not related to this patch. http://newtestbot.winehq.org/JobDetails.pl?Key=824 After a EM_GETHANDLE, the app is the owner of the text buffer memory handle and the app is responsible for the LocalFree(). Behavior of messages is undocumented after EM_GETHANDLE Some messages return a previous result (EM_GETHANDLE or WM_GETTEXTLENGTH). Some messages just fail (WM_SETTEXT, which does not create a new buffer). After the app LocalFree() the old memory handle, various messages crash the app (EM_GETHANDLE or WM_SETTEXT as examples) -- By by ... Detlef --- dlls/user32/edit.c | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 74e0ea4..d9e2ff9 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -151,6 +151,7 @@ typedef struct HLOCAL hloc32W; /* our unicode local memory block */ HLOCAL hloc32A; /* alias for ANSI control receiving EM_GETHANDLE or EM_SETHANDLE */ + HLOCAL hlocapp; /* The text buffer handle belongs to the app */ /* * IME Data */ @@ -1264,6 +1265,10 @@ static inline void text_buffer_changed(EDITSTATE *es) */ static void EDIT_LockBuffer(EDITSTATE *es) { + /* The text buffer handle belongs to the app */ + if(es->hlocapp) + return; + if (!es->text) { if(!es->hloc32W) return; @@ -1305,6 +1310,9 @@ static void EDIT_LockBuffer(EDITSTATE *es) */ static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force) { + /* The text buffer handle belongs to the app */ + if(es->hlocapp) + return; /* Edit window might be already destroyed */ if(!IsWindow(es->hwndSelf)) @@ -1353,7 +1361,7 @@ static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force) LocalUnlock(es->hloc32A); } - LocalUnlock(es->hloc32W); + if (es->text) LocalUnlock(es->hloc32W); es->text = NULL; } else { @@ -2485,6 +2493,11 @@ static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es) hLocal = es->hloc32A; } + EDIT_UnlockBuffer(es, TRUE); + + /* The text buffer handle belongs to the app */ + es->hlocapp = hLocal; + /* The app has knowledge of the text buffer handle */ es->flags |= EF_APP_HAS_HANDLE; TRACE("Returning %p, LocalSize() = %ld\n", hLocal, LocalSize(hLocal)); return hLocal; @@ -2826,6 +2839,9 @@ static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc) es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1; + /* The text buffer handle belongs to the control */ + es->hlocapp = NULL; + /* The app has knowledge of the text buffer handle */ es->flags |= EF_APP_HAS_HANDLE; EDIT_LockBuffer(es); @@ -4597,10 +4613,11 @@ static LRESULT EDIT_WM_NCDestroy(EDITSTATE *es) { LINEDEF *pc, *pp; - if (es->hloc32W) { + /* The app can own the text buffer handle */ + if (es->hloc32W && (es->hloc32W != es->hlocapp)) { LocalFree(es->hloc32W); } - if (es->hloc32A) { + if (es->hloc32A && (es->hloc32A != es->hlocapp)) { LocalFree(es->hloc32A); } EDIT_InvalidateUniscribeData(es); -- 1.7.5.4