@@ -281,7 +281,9 @@ struct _SearchData
281281 CStringA szQueryU8;
282282 BOOL SearchHidden;
283283 CComPtr<CFindFolder> pFindFolder;
284+ UINT SearchId;
284285
286+ explicit _SearchData (UINT InitSearchId) : SearchId(InitSearchId) {}
285287 ~_SearchData ()
286288 {
287289 FreeList (pPaths);
@@ -528,6 +530,15 @@ static BOOL AttribHiddenMatch(DWORD FileAttributes, _SearchData *pSearchData)
528530 return FALSE ;
529531}
530532
533+ static inline void PostUpdate (UINT Msg, LPCWSTR pszText, const _SearchData &Data)
534+ {
535+ LPWSTR pszDup;
536+ if (FAILED (SHStrDupW (pszText, &pszDup)))
537+ return ;
538+ if (!PostMessageW (Data.hwnd , Msg, Data.SearchId , (LPARAM )pszDup))
539+ SHFree (pszDup);
540+ }
541+
531542static UINT RecursiveFind (LPCWSTR lpPath, _SearchData *pSearchData)
532543{
533544 if (WaitForSingleObject (pSearchData->hStopEvent , 0 ) != WAIT_TIMEOUT )
@@ -558,26 +569,20 @@ static UINT RecursiveFind(LPCWSTR lpPath, _SearchData *pSearchData)
558569 FileNameMatch (FindData.cFileName , pSearchData) &&
559570 AttribHiddenMatch (FindData.dwFileAttributes , pSearchData))
560571 {
561- LPWSTR pszPathDup;
562- SHStrDupW (szPath, &pszPathDup);
563- PostMessageW (pSearchData->hwnd , WM_SEARCH_ADD_RESULT , 0 , (LPARAM )pszPathDup);
572+ PostUpdate (WM_SEARCH_ADD_RESULT , szPath, *pSearchData);
564573 uTotalFound++;
565574 }
566575 status.Format (IDS_SEARCH_FOLDER , FindData.cFileName );
567- LPWSTR pszStatusDup;
568- SHStrDupW (status.GetBuffer (), &pszStatusDup);
569- PostMessageW (pSearchData->hwnd , WM_SEARCH_UPDATE_STATUS , 0 , (LPARAM )pszStatusDup);
576+ PostUpdate (WM_SEARCH_UPDATE_STATUS , status.GetBuffer (), *pSearchData);
570577
571578 uTotalFound += RecursiveFind (szPath, pSearchData);
572579 }
573580 else if (FileNameMatch (FindData.cFileName , pSearchData)
574581 && AttribHiddenMatch (FindData.dwFileAttributes , pSearchData)
575582 && ContentsMatch (szPath, pSearchData))
576583 {
584+ PostUpdate (WM_SEARCH_ADD_RESULT , szPath, *pSearchData);
577585 uTotalFound++;
578- LPWSTR pszPathDup;
579- SHStrDupW (szPath, &pszPathDup);
580- PostMessageW (pSearchData->hwnd , WM_SEARCH_ADD_RESULT , 0 , (LPARAM )pszPathDup);
581586 }
582587 }
583588
@@ -607,9 +612,7 @@ DWORD WINAPI CFindFolder::SearchThreadProc(LPVOID lpParameter)
607612
608613 CStringW status;
609614 status.Format (IDS_SEARCH_FILES_FOUND , uTotalFound);
610- LPWSTR pszStatusDup;
611- SHStrDupW (status.GetBuffer (), &pszStatusDup);
612- ::PostMessageW (data->hwnd, WM_SEARCH_UPDATE_STATUS , 0 , (LPARAM )pszStatusDup);
615+ PostUpdate (WM_SEARCH_UPDATE_STATUS , status.GetBuffer (), *data);
613616 ::SendMessageW (data->hwnd, WM_SEARCH_STOP , 0 , 0 );
614617
615618 CloseHandle (data->hStopEvent );
@@ -652,7 +655,7 @@ LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
652655 UINT uItemIndex;
653656 m_shellFolderView->RemoveObject (NULL , &uItemIndex);
654657
655- _SearchData* pSearchData = new _SearchData ();
658+ _SearchData* pSearchData = new _SearchData (++m_SearchId );
656659 pSearchData->pFindFolder = this ;
657660 pSearchData->hwnd = m_hWnd;
658661
@@ -743,6 +746,16 @@ LRESULT CFindFolder::StopSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
743746 {
744747 SetEvent (m_hStopEvent);
745748 m_hStopEvent = NULL ;
749+
750+ // Wait for all in-flight messages with data we need to free
751+ PostMessageW (WM_SEARCH_STOPPED , 0 , 0 );
752+ for (MSG msg; PeekMessageW (&msg, m_hWnd, WM_SEARCH_START , WM_SEARCH_STOPPED , PM_REMOVE );)
753+ {
754+ if (msg.message == WM_SEARCH_STOPPED )
755+ break ;
756+ if (msg.message == WM_SEARCH_ADD_RESULT || msg.message == WM_SEARCH_UPDATE_STATUS )
757+ SHFree ((void *)msg.lParam );
758+ }
746759 }
747760 return 0 ;
748761}
@@ -753,6 +766,8 @@ LRESULT CFindFolder::AddResult(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bH
753766 return 0 ;
754767
755768 CComHeapPtr<WCHAR > lpPath ((LPWSTR ) lParam);
769+ if (wParam != m_SearchId)
770+ return 0 ;
756771
757772 CComHeapPtr<ITEMIDLIST > lpSearchPidl (_ILCreate (lpPath));
758773 if (lpSearchPidl)
@@ -767,11 +782,8 @@ LRESULT CFindFolder::AddResult(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bH
767782LRESULT CFindFolder::UpdateStatus (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
768783{
769784 CComHeapPtr<WCHAR > status ((LPWSTR ) lParam);
770- if (m_shellBrowser)
771- {
785+ if (m_shellBrowser && wParam == m_SearchId)
772786 m_shellBrowser->SetStatusTextSB (status);
773- }
774-
775787 return 0 ;
776788}
777789
@@ -1211,6 +1223,11 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
12111223 }
12121224 case SFVM_WINDOWCLOSING :
12131225 {
1226+ SendMessage (WM_SEARCH_STOP , 0 , 0 );
1227+
1228+ // [CORE-20504] LVN_ITEMACTIVATE in the DefView ListView can trigger a navigation that destroys this IShellFolder,
1229+ // unsubclass now so we don't get a message after our "this" is dead.
1230+ UnsubclassWindow ();
12141231 m_shellFolderView = NULL ;
12151232 m_shellBrowser = NULL ;
12161233 return S_OK ;
0 commit comments