ReactOS  0.4.15-dev-449-g64abd9f
CFindFolder.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Search Shell Extension
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Search results folder
5  * COPYRIGHT: Copyright 2019 Brock Mammen
6  */
7 
8 #include "CFindFolder.h"
9 #include <exdispid.h>
10 
12 
13 static HRESULT SHELL32_CoCreateInitSF(LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO* ppfti,
14  LPCITEMIDLIST pidlChild, const GUID* clsid, REFIID riid, LPVOID *ppvOut)
15 {
16  HRESULT hr;
17  CComPtr<IShellFolder> pShellFolder;
18 
20  if (FAILED(hr))
21  return hr;
22 
23  LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
26 
27  if (ppfti && SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3))))
28  {
29  ppf3->InitializeEx(NULL, pidlAbsolute, ppfti);
30  }
31  else if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &ppf))))
32  {
33  ppf->Initialize(pidlAbsolute);
34  }
35  ILFree (pidlAbsolute);
36 
37  return pShellFolder->QueryInterface(riid, ppvOut);
38 }
39 
41  HMENU hMenu,
42  UINT indexMenu,
43  BOOL fByPosition,
44  UINT wID,
45  UINT fType,
46  LPCWSTR dwTypeData,
47  UINT fState)
48 {
49  MENUITEMINFOW mii;
50  WCHAR wszText[100];
51 
52  ZeroMemory(&mii, sizeof(mii));
53  mii.cbSize = sizeof(mii);
54  if (fType == MFT_SEPARATOR)
55  mii.fMask = MIIM_ID | MIIM_TYPE;
56  else if (fType == MFT_STRING)
57  {
59  if (IS_INTRESOURCE(dwTypeData))
60  {
61  if (LoadStringW(_AtlBaseModule.GetResourceInstance(), LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
62  mii.dwTypeData = wszText;
63  else
64  {
65  ERR("failed to load string %p\n", dwTypeData);
66  return;
67  }
68  }
69  else
70  mii.dwTypeData = (LPWSTR)dwTypeData;
71  mii.fState = fState;
72  }
73 
74  mii.wID = wID;
75  mii.fType = fType;
76  InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
77 }
78 
79 struct FolderViewColumns
80 {
81  int iResource;
83  int fmt;
84  int cxChar;
85 };
86 
88 {
92 };
93 
95  m_hStopEvent(NULL)
96 {
97 }
98 
99 static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath)
100 {
101  CComHeapPtr<ITEMIDLIST> lpFSPidl(ILCreateFromPathW(lpszPath));
102  if (!lpFSPidl)
103  {
104  ERR("Failed to create pidl from path\n");
105  return NULL;
106  }
107  LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl);
108 
109  int pathLen = (PathFindFileNameW(lpszPath) - lpszPath) * sizeof(WCHAR);
110  int cbData = sizeof(WORD) + pathLen + lpLastFSPidl->mkid.cb;
111  LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(cbData + sizeof(WORD));
112  if (!pidl)
113  return NULL;
114 
115  LPBYTE p = (LPBYTE) pidl;
116  *((WORD *) p) = cbData;
117  p += sizeof(WORD);
118 
119  memcpy(p, lpszPath, pathLen);
120  p += pathLen - sizeof(WCHAR);
121  *((WCHAR *) p) = '\0';
122  p += sizeof(WCHAR);
123 
124  memcpy(p, lpLastFSPidl, lpLastFSPidl->mkid.cb);
125  p += lpLastFSPidl->mkid.cb;
126 
127  *((WORD *) p) = 0;
128 
129  return pidl;
130 }
131 
133 {
134  if (!pidl || !pidl->mkid.cb)
135  return NULL;
136  return (LPCWSTR) pidl->mkid.abID;
137 }
138 
140 {
141  if (!pidl || !pidl->mkid.cb)
142  return pidl;
143  return (LPCITEMIDLIST) ((LPBYTE) pidl->mkid.abID
144  + ((wcslen((LPCWSTR) pidl->mkid.abID) + 1) * sizeof(WCHAR)));
145 }
146 
148 {
157 };
158 
159 template<typename TChar, typename TString, int (&StrNCmp)(const TChar *, const TChar *, size_t)>
160 static const TChar* StrStrN(const TChar *lpFirst, const TString &lpSrch, UINT cchMax)
161 {
162  if (!lpFirst || lpSrch.IsEmpty() || !cchMax)
163  return NULL;
164 
165  for (UINT i = cchMax; i > 0 && *lpFirst; i--, lpFirst++)
166  {
167  if (!StrNCmp(lpFirst, lpSrch, lpSrch.GetLength()))
168  return (const TChar*)lpFirst;
169  }
170 
171  return NULL;
172 }
173 
174 template<typename TChar, typename TString, int (&StrNCmp)(const TChar *, const TChar *, size_t)>
175 static UINT StrStrNCount(const TChar *lpFirst, const TString &lpSrch, UINT cchMax)
176 {
177  const TChar *lpSearchEnd = lpFirst + cchMax;
178  UINT uCount = 0;
179  while (lpFirst < lpSearchEnd && (lpFirst = StrStrN<TChar, TString, StrNCmp>(lpFirst, lpSrch, cchMax)))
180  {
181  uCount++;
182  lpFirst += lpSrch.GetLength();
183  cchMax = lpSearchEnd - lpFirst;
184  }
185  return uCount;
186 }
187 
188 static UINT StrStrCountNIA(const CHAR *lpFirst, const CStringA &lpSrch, UINT cchMax)
189 {
190  return StrStrNCount<CHAR, CStringA, _strnicmp>(lpFirst, lpSrch, cchMax);
191 }
192 
193 static UINT StrStrCountNIW(const WCHAR *lpFirst, const CStringW &lpSrch, UINT cchMax)
194 {
195  return StrStrNCount<WCHAR, CStringW, _wcsnicmp>(lpFirst, lpSrch, cchMax);
196 }
197 
198 static UINT SearchFile(LPCWSTR lpFilePath, _SearchData *pSearchData)
199 {
202  return 0;
203 
205  HANDLE hFileMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
207  if (hFileMap == INVALID_HANDLE_VALUE)
208  return 0;
209 
210  LPBYTE lpFileContent = (LPBYTE) MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
211  CloseHandle(hFileMap);
212  if (!lpFileContent)
213  return 0;
214 
215  UINT uMatches = 0;
216  // Check for UTF-16 BOM
217  if (size >= 2 && lpFileContent[0] == 0xFF && lpFileContent[1] == 0xFE)
218  {
219  uMatches = StrStrCountNIW((LPCWSTR) lpFileContent, pSearchData->szQueryW, size / sizeof(WCHAR));
220  }
221  else
222  {
223  uMatches = StrStrCountNIA((LPCSTR) lpFileContent, pSearchData->szQueryA, size / sizeof(CHAR));
224  }
225 
226  UnmapViewOfFile(lpFileContent);
227 
228  return uMatches;
229 }
230 
231 static BOOL FileNameMatch(LPCWSTR FindDataFileName, _SearchData *pSearchData)
232 {
233  if (pSearchData->szFileName.IsEmpty() || PathMatchSpecW(FindDataFileName, pSearchData->szFileName))
234  {
235  return TRUE;
236  }
237  return FALSE;
238 }
239 
241 {
242  if (pSearchData->szQueryA.IsEmpty() || SearchFile(szPath, pSearchData))
243  {
244  return TRUE;
245  }
246  return FALSE;
247 }
248 
250 {
251  if (!(FileAttributes & FILE_ATTRIBUTE_HIDDEN) || (pSearchData->SearchHidden))
252  {
253  return TRUE;
254  }
255  return FALSE;
256 }
257 
258 static UINT RecursiveFind(LPCWSTR lpPath, _SearchData *pSearchData)
259 {
260  if (WaitForSingleObject(pSearchData->hStopEvent, 0) != WAIT_TIMEOUT)
261  return 0;
262 
264  WIN32_FIND_DATAW FindData;
265  HANDLE hFindFile;
266  BOOL bMoreFiles = TRUE;
267  UINT uTotalFound = 0;
268 
269  PathCombineW(szPath, lpPath, L"*.*");
270 
271  for (hFindFile = FindFirstFileW(szPath, &FindData);
272  bMoreFiles && hFindFile != INVALID_HANDLE_VALUE;
273  bMoreFiles = FindNextFileW(hFindFile, &FindData))
274  {
275  if (!wcscmp(FindData.cFileName, L".") || !wcscmp(FindData.cFileName, L".."))
276  continue;
277 
278  PathCombineW(szPath, lpPath, FindData.cFileName);
279 
280  if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
281  {
283  if (FileNameMatch(FindData.cFileName, pSearchData)
284  && AttribHiddenMatch(FindData.dwFileAttributes, pSearchData))
285  {
287  uTotalFound++;
288  }
289  status.Format(IDS_SEARCH_FOLDER, FindData.cFileName);
290  PostMessageW(pSearchData->hwnd, WM_SEARCH_UPDATE_STATUS, 0, (LPARAM) StrDupW(status.GetBuffer()));
291 
292  uTotalFound += RecursiveFind(szPath, pSearchData);
293  }
294  else if (FileNameMatch(FindData.cFileName, pSearchData)
295  && AttribHiddenMatch(FindData.dwFileAttributes, pSearchData)
296  && ContentsMatch(szPath, pSearchData))
297  {
298  uTotalFound++;
300  }
301  }
302 
303  if (hFindFile != INVALID_HANDLE_VALUE)
304  FindClose(hFindFile);
305 
306  return uTotalFound;
307 }
308 
310 {
311  _SearchData *data = static_cast<_SearchData*>(lpParameter);
312 
313  data->pFindFolder->NotifyConnections(DISPID_SEARCHSTART);
314 
315  UINT uTotalFound = RecursiveFind(data->szPath, data);
316 
317  data->pFindFolder->NotifyConnections(DISPID_SEARCHCOMPLETE);
318 
320  status.Format(IDS_SEARCH_FILES_FOUND, uTotalFound);
321  ::PostMessageW(data->hwnd, WM_SEARCH_UPDATE_STATUS, 0, (LPARAM) StrDupW(status.GetBuffer()));
322  ::SendMessageW(data->hwnd, WM_SEARCH_STOP, 0, 0);
323 
324  CloseHandle(data->hStopEvent);
325  delete data;
326 
327  return 0;
328 }
329 
331 {
332  DISPPARAMS dispatchParams = {0};
333  CComDynamicUnkArray &subscribers =
335  for (IUnknown** pSubscriber = subscribers.begin(); pSubscriber < subscribers.end(); pSubscriber++)
336  {
337  if (!*pSubscriber)
338  continue;
339 
340  CComPtr<IDispatch> pDispatch;
341  HRESULT hResult = (*pSubscriber)->QueryInterface(IID_PPV_ARG(IDispatch, &pDispatch));
342  if (!FAILED_UNEXPECTEDLY(hResult))
343  pDispatch->Invoke(id, GUID_NULL, 0, DISPATCH_METHOD, &dispatchParams, NULL, NULL, NULL);
344  }
345 }
346 
348 {
349  HKEY hkey;
350  DWORD size = sizeof(DWORD);
351  DWORD result;
352  DWORD SearchHiddenValue = 0;
353 
354  if (!lParam)
355  return 0;
356 
357  // Clear all previous search results
358  UINT uItemIndex;
359  m_shellFolderView->RemoveObject(NULL, &uItemIndex);
360 
361  _SearchData* pSearchData = new _SearchData();
362  pSearchData->pFindFolder = this;
363  pSearchData->hwnd = m_hWnd;
364 
365  SearchStart *pSearchParams = (SearchStart *) lParam;
366  pSearchData->szPath = pSearchParams->szPath;
367  pSearchData->szFileName = pSearchParams->szFileName;
368  pSearchData->szQueryA = pSearchParams->szQuery;
369  pSearchData->szQueryW = pSearchParams->szQuery;
370  pSearchData->SearchHidden = pSearchParams->SearchHidden;
371  SHFree(pSearchParams);
372 
373  TRACE("pSearchParams->SearchHidden is '%d'.\n", pSearchData->SearchHidden);
374 
375  if (pSearchData->SearchHidden)
376  SearchHiddenValue = 1;
377  else
378  SearchHiddenValue = 0;
379 
380  /* Placing the code to save the changed settings to the registry here has the effect of not saving any changes */
381  /* to the registry unless the user clicks on the "Search" button. This is the same as what we see in Windows. */
382  result = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", 0, KEY_SET_VALUE, &hkey);
383  if (result == ERROR_SUCCESS)
384  {
385  if (RegSetValueExW(hkey, L"SearchHidden", NULL, REG_DWORD, (const BYTE*)&SearchHiddenValue, size) == ERROR_SUCCESS)
386  {
387  TRACE("SearchHidden is '%d'.\n", SearchHiddenValue);
388  }
389  else
390  {
391  ERR("RegSetValueEx for \"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SearchHidden\" Failed.\n");
392  }
393  RegCloseKey(hkey);
394  }
395  else
396  {
397  ERR("RegOpenKey for \"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\" Failed.\n");
398  }
399 
400  if (m_hStopEvent)
402  pSearchData->hStopEvent = m_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
403 
404  if (!SHCreateThread(SearchThreadProc, pSearchData, NULL, NULL))
405  {
406  SHFree(pSearchData);
407  return 0;
408  }
409 
410  return 0;
411 }
412 
414 {
415  if (m_hStopEvent)
416  {
418  m_hStopEvent = NULL;
419  }
420  return 0;
421 }
422 
424 {
425  if (!lParam)
426  return 0;
427 
428  CComHeapPtr<WCHAR> lpPath((LPWSTR) lParam);
429 
430  CComHeapPtr<ITEMIDLIST> lpSearchPidl(_ILCreate(lpPath));
431  if (lpSearchPidl)
432  {
433  UINT uItemIndex;
434  m_shellFolderView->AddObject(lpSearchPidl, &uItemIndex);
435  }
436 
437  return 0;
438 }
439 
441 {
443  if (m_shellBrowser)
444  {
445  m_shellBrowser->SetStatusTextSB(status);
446  }
447 
448  return 0;
449 }
450 
451 // *** IShellFolder2 methods ***
453 {
455  return E_NOTIMPL;
456 }
457 
459 {
461  return E_NOTIMPL;
462 }
463 
465 {
466  if (pSort)
467  *pSort = 0;
468  if (pDisplay)
469  *pDisplay = 0;
470  return S_OK;
471 }
472 
474 {
475  if (!pcsFlags)
476  return E_INVALIDARG;
477  if (iColumn >= _countof(g_ColumnDefs))
478  return m_pisfInner->GetDefaultColumnState(iColumn - _countof(g_ColumnDefs) + 1, pcsFlags);
479  *pcsFlags = g_ColumnDefs[iColumn].dwDefaultState;
480  return S_OK;
481 }
482 
484 {
485  return m_pisfInner->GetDetailsEx(pidl, pscid, pv);
486 }
487 
489 {
490  if (iColumn >= _countof(g_ColumnDefs))
491  return m_pisfInner->GetDetailsOf(_ILGetFSPidl(pidl), iColumn - _countof(g_ColumnDefs) + 1, pDetails);
492 
493  pDetails->cxChar = g_ColumnDefs[iColumn].cxChar;
494  pDetails->fmt = g_ColumnDefs[iColumn].fmt;
495 
496  if (!pidl)
497  return SHSetStrRet(&pDetails->str, _AtlBaseModule.GetResourceInstance(), g_ColumnDefs[iColumn].iResource);
498 
499  if (iColumn == 1)
500  {
501  return SHSetStrRet(&pDetails->str, _ILGetPath(pidl));
502  }
503 
504  return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str);
505 }
506 
508 {
510  return E_NOTIMPL;
511 }
512 
513 // *** IShellFolder methods ***
514 STDMETHODIMP CFindFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten,
515  PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
516 {
518  return E_NOTIMPL;
519 }
520 
521 STDMETHODIMP CFindFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
522 {
523  *ppEnumIDList = NULL;
524  return S_FALSE;
525 }
526 
528 {
530  return E_NOTIMPL;
531 }
532 
534 {
536  return E_NOTIMPL;
537 }
538 
540 {
541  return m_pisfInner->CompareIDs(lParam, _ILGetFSPidl(pidl1), _ILGetFSPidl(pidl2));
542 }
543 
545 {
546  if (riid == IID_IShellView)
547  {
548  SFV_CREATE sfvparams = {};
549  sfvparams.cbSize = sizeof(SFV_CREATE);
550  sfvparams.pshf = this;
551  sfvparams.psfvcb = this;
552  HRESULT hr = SHCreateShellFolderView(&sfvparams, (IShellView **) ppvOut);
553  if (FAILED_UNEXPECTEDLY(hr))
554  {
555  return hr;
556  }
557 
558  return ((IShellView * ) * ppvOut)->QueryInterface(IID_PPV_ARG(IShellFolderView, &m_shellFolderView));
559  }
560  return E_NOINTERFACE;
561 }
562 
564 {
566  aFSPidl.Allocate(cidl);
567  for (UINT i = 0; i < cidl; i++)
568  {
569  aFSPidl[i] = _ILGetFSPidl(apidl[i]);
570  }
571 
572  return m_pisfInner->GetAttributesOf(cidl, aFSPidl, rgfInOut);
573 }
574 
576  public IContextMenu,
577  public CComObjectRootEx<CComMultiThreadModelNoCS>
578 {
582  static const UINT ADDITIONAL_MENU_ITEMS = 2;
583 
585  STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
586  {
587  m_firstCmdId = indexMenu;
589  _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst++, MFT_SEPARATOR, NULL, 0);
590  return m_pInner->QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
591  }
592 
594  {
595  if (!IS_INTRESOURCE(lpcmi->lpVerb))
596  {
597  return m_pInner->InvokeCommand(lpcmi);
598  }
599 
601  {
602  PCUITEMID_CHILD *apidl;
603  UINT cidl;
604  HRESULT hResult = m_shellFolderView->GetSelectedObjects(&apidl, &cidl);
605  if (FAILED_UNEXPECTEDLY(hResult))
606  return hResult;
607 
608  for (UINT i = 0; i < cidl; i++)
609  {
611  if (!folderPidl)
612  return E_OUTOFMEMORY;
613  CComHeapPtr<ITEMIDLIST> filePidl(ILCombine(folderPidl, _ILGetFSPidl(apidl[i])));
614  if (!filePidl)
615  return E_OUTOFMEMORY;
616  SHOpenFolderAndSelectItems(folderPidl, 1, &filePidl, 0);
617  }
618  return S_OK;
619  }
620 
621  CMINVOKECOMMANDINFOEX actualCmdInfo;
622  memcpy(&actualCmdInfo, lpcmi, lpcmi->cbSize);
623  actualCmdInfo.lpVerb -= ADDITIONAL_MENU_ITEMS;
624  return m_pInner->InvokeCommand((CMINVOKECOMMANDINFO *)&actualCmdInfo);
625  }
626 
627  STDMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
628  {
629  return m_pInner->GetCommandString(idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
630  }
631 
632 public:
633  static HRESULT Create(IShellFolderView *pShellFolderView, IContextMenu *pInnerContextMenu, IContextMenu **pContextMenu)
634  {
637  if (FAILED_UNEXPECTEDLY(hResult))
638  return hResult;
639  pObj->m_shellFolderView = pShellFolderView;
640  pObj->m_pInner = pInnerContextMenu;
641  return pObj->QueryInterface(IID_PPV_ARG(IContextMenu, pContextMenu));
642  }
643 
645  COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
646  END_COM_MAP()
647 };
648 
650  UINT *prgfInOut, LPVOID *ppvOut)
651 {
652  if (cidl <= 0)
653  {
654  return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
655  }
656 
658  aFSPidl.Allocate(cidl);
659  for (UINT i = 0; i < cidl; i++)
660  {
661  aFSPidl[i] = _ILGetFSPidl(apidl[i]);
662  }
663 
664  if (riid == IID_IContextMenu)
665  {
667  if (!folderPidl)
668  return E_OUTOFMEMORY;
669  CComPtr<IShellFolder> pDesktopFolder;
670  HRESULT hResult = SHGetDesktopFolder(&pDesktopFolder);
671  if (FAILED_UNEXPECTEDLY(hResult))
672  return hResult;
673  CComPtr<IShellFolder> pShellFolder;
674  hResult = pDesktopFolder->BindToObject(folderPidl, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
675  if (FAILED_UNEXPECTEDLY(hResult))
676  return hResult;
677  CComPtr<IContextMenu> pContextMenu;
678  hResult = pShellFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, (LPVOID *)&pContextMenu);
679  if (FAILED_UNEXPECTEDLY(hResult))
680  return hResult;
681  return CFindFolderContextMenu::Create(m_shellFolderView, pContextMenu, (IContextMenu **)ppvOut);
682  }
683 
684  return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut);
685 }
686 
688 {
689  return m_pisfInner->GetDisplayNameOf(_ILGetFSPidl(pidl), dwFlags, pName);
690 }
691 
693  PITEMID_CHILD *pPidlOut)
694 {
696  return E_NOTIMPL;
697 }
698 
701 {
702  switch (uMsg)
703  {
704  case SFVM_DEFVIEWMODE:
705  {
706  FOLDERVIEWMODE *pViewMode = (FOLDERVIEWMODE *) lParam;
707  *pViewMode = FVM_DETAILS;
708  return S_OK;
709  }
710  case SFVM_WINDOWCREATED:
711  {
712  // Subclass window to receive window messages
714 
715  // Get shell browser for updating status bar text
716  CComPtr<IServiceProvider> pServiceProvider;
717  HRESULT hr = m_shellFolderView->QueryInterface(IID_PPV_ARG(IServiceProvider, &pServiceProvider));
718  if (FAILED_UNEXPECTEDLY(hr))
719  return hr;
720  hr = pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser));
721  if (FAILED_UNEXPECTEDLY(hr))
722  return hr;
723 
724  // Open search bar
725  CComPtr<IWebBrowser2> pWebBrowser2;
726  hr = m_shellBrowser->QueryInterface(IID_PPV_ARG(IWebBrowser2, &pWebBrowser2));
727  if (FAILED_UNEXPECTEDLY(hr))
728  return hr;
729  WCHAR pwszGuid[MAX_PATH];
730  StringFromGUID2(CLSID_FileSearchBand, pwszGuid, _countof(pwszGuid));
731  CComVariant searchBar(pwszGuid);
732  return pWebBrowser2->ShowBrowserBar(&searchBar, NULL, NULL);
733  }
734  }
735  return E_NOTIMPL;
736 }
737 
740 {
741  *pidl = ILClone(m_pidl);
742  return S_OK;
743 }
744 
745 // *** IPersistFolder methods ***
747 {
748  m_pidl = ILClone(pidl);
749  if (!m_pidl)
750  return E_OUTOFMEMORY;
751 
753  NULL,
754  NULL,
755  &CLSID_ShellFSFolder,
757 }
758 
759 // *** IPersist methods ***
761 {
762  if (pClassId == NULL)
763  return E_INVALIDARG;
764  *pClassId = CLSID_FindFolder;
765  return S_OK;
766 }
#define CreateEvent
Definition: winbase.h:3588
STDMETHODIMP BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
DWORD dwDefaultState
Definition: CFontExt.cpp:17
#define WM_SEARCH_ADD_RESULT
Definition: shellfind.h:31
IUnknown ** begin()
Definition: atlcom.h:1064
#define MFT_STRING
Definition: winuser.h:741
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
CStringW szQueryW
#define CloseHandle
Definition: compat.h:407
STDMETHODIMP GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
#define E_NOINTERFACE
Definition: winerror.h:2364
CStringA szQueryA
CComPtr< CFindFolder > pFindFolder
#define ERROR_SUCCESS
Definition: deptool.c:10
#define MapViewOfFile
Definition: compat.h:411
STDMETHODIMP GetDefaultSearchGUID(GUID *pguid)
HRESULT hr
Definition: shlfolder.c:183
#define KEY_SET_VALUE
Definition: nt_native.h:1017
IShellFolderViewCB * psfvcb
Definition: shlobj.h:1285
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
HANDLE m_hStopEvent
Definition: CFindFolder.h:70
LPITEMIDLIST m_pidl
Definition: CFindFolder.h:66
interface IBindCtx * LPBC
Definition: objfwd.h:18
REFIID riid
Definition: precomp.h:44
static UINT StrStrCountNIW(const WCHAR *lpFirst, const CStringW &lpSrch, UINT cchMax)
static BOOL ContentsMatch(LPCWSTR szPath, _SearchData *pSearchData)
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char CHAR
Definition: xmlstorage.h:175
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:699
EXTERN_C HRESULT WINAPI SHOpenFolderAndSelectItems(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD dwFlags)
Definition: shlfolder.cpp:389
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
_In_ LPCSTR lpName
Definition: winbase.h:2752
#define IDS_COL_NAME
Definition: resource.h:6
#define LVCFMT_LEFT
Definition: commctrl.h:2594
#define INVALID_HANDLE_VALUE
Definition: compat.h:400
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
#define IDS_COL_LOCATION
Definition: resource.h:170
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define ZeroMemory
Definition: winbase.h:1648
LPWSTR dwTypeData
Definition: winuser.h:3244
#define IDS_SEARCH_FOLDER
Definition: resource.h:173
LRESULT StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
UINT_PTR WPARAM
Definition: windef.h:207
UINT uFlags
Definition: api.c:59
char * LPSTR
Definition: xmlstorage.h:182
static DWORD WINAPI SearchThreadProc(LPVOID lpParameter)
static void WINAPI _InsertMenuItemW(HMENU hMenu, UINT indexMenu, BOOL fByPosition, UINT wID, UINT fType, LPCWSTR dwTypeData, UINT fState)
Definition: CFindFolder.cpp:40
static LPOLESTR
Definition: stg_prop.c:27
LRESULT StopSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, IShellView **ppsv)
Definition: CDefView.cpp:3594
#define IID_PPV_ARG(Itype, ppType)
LPWSTR WINAPI StrDupW(LPCWSTR lpszStr)
Definition: string.c:1089
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define DWORD
Definition: nt_native.h:44
STRRET str
Definition: shtypes.idl:108
static LPCWSTR _ILGetPath(LPCITEMIDLIST pidl)
WPARAM wParam
Definition: combotst.c:138
#define DISPATCH_METHOD
Definition: oleauto.h:1006
STDMETHODIMP GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
uint32_t ULONG_PTR
Definition: typedefs.h:64
STDMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static BOOL AttribHiddenMatch(DWORD FileAttributes, _SearchData *pSearchData)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
STDMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define MFS_ENABLED
Definition: winuser.h:745
WCHAR szQuery[MAX_PATH]
Definition: shellfind.h:38
static UINT RecursiveFind(LPCWSTR lpPath, _SearchData *pSearchData)
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
CStringW szFileName
#define MIIM_STATE
Definition: winuser.h:716
unsigned int BOOL
Definition: ntddk_ex.h:94
CStringW szPath
WINE_DEFAULT_DEBUG_CHANNEL(shellfind)
STDMETHODIMP GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *pDetails)
#define IDS_COL_RELEVANCE
Definition: resource.h:171
bool Allocate(_In_ size_t nElements=1)
Definition: atlalloc.h:143
STDMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName)
#define DISPID_SEARCHSTART
Definition: exdispid.h:172
#define STDMETHODIMP
Definition: basetyps.h:43
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
STDMETHODIMP BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
smooth NULL
Definition: ftsmooth.c:416
static const UINT ADDITIONAL_MENU_ITEMS
STDMETHODIMP GetClassID(CLSID *pClassId)
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:389
LONG_PTR LPARAM
Definition: windef.h:208
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
#define DISPID_SEARCHCOMPLETE
Definition: exdispid.h:173
static UINT StrStrNCount(const TChar *lpFirst, const TString &lpSrch, UINT cchMax)
STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
#define FILE_MAP_READ
Definition: compat.h:436
FOLDERVIEWMODE
Definition: shobjidl.idl:663
static HRESULT Create(IShellFolderView *pShellFolderView, IContextMenu *pInnerContextMenu, IContextMenu **pContextMenu)
const char * LPCSTR
Definition: xmlstorage.h:183
struct _SFV_CREATE SFV_CREATE
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1230
HRESULT WINAPI SHCoCreateInstance(LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID refiid, LPVOID *ppv)
Definition: shellole.c:105
WCHAR szFileName[MAX_PATH]
Definition: shellfind.h:37
#define OPEN_EXISTING
Definition: compat.h:435
CComPtr< IShellFolder2 > m_pisfInner
Definition: CFindFolder.h:67
#define MIIM_ID
Definition: winuser.h:717
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:541
#define IDS_SEARCH_OPEN_FOLDER
Definition: resource.h:175
#define IDS_SEARCH_FILES_FOUND
Definition: resource.h:172
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
STDMETHODIMP GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
GLsizeiptr size
Definition: glext.h:5919
static BOOL FileNameMatch(LPCWSTR FindDataFileName, _SearchData *pSearchData)
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
LRESULT UpdateStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SFVM_WINDOWCREATED
Definition: shlobj.h:1235
LONG HRESULT
Definition: typedefs.h:78
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:410
#define _countof(array)
Definition: sndvol32.h:68
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define MAX_PATH
Definition: compat.h:26
static UINT StrStrCountNIA(const CHAR *lpFirst, const CStringA &lpSrch, UINT cchMax)
#define WINAPI
Definition: msvc.h:6
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
STDMETHODIMP GetCurFolder(PIDLIST_ABSOLUTE *pidl)
STDMETHODIMP GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
STDMETHODIMP CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, LPVOID *ppvOut)
#define WAIT_TIMEOUT
Definition: dderror.h:14
UINT cchMax
static LPCITEMIDLIST _ILGetFSPidl(LPCITEMIDLIST pidl)
#define MFT_SEPARATOR
Definition: winuser.h:739
STDMETHODIMP CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
void NotifyConnections(DISPID id)
REFCLSID clsid
Definition: msctf.c:82
#define SFVM_DEFVIEWMODE
Definition: shlobj.h:1245
static const WCHAR L[]
Definition: oid.c:1250
static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath)
Definition: CFindFolder.cpp:99
STDMETHODIMP EnumSearches(IEnumExtraSearch **ppenum)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MIIM_TYPE
Definition: winuser.h:720
LPVOID lpParameter
Definition: kernel32.h:241
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GUID_NULL
Definition: ks.h:106
#define StrNCmp
Definition: shlwapi.h:1524
HWND m_hWnd
Definition: atlwin.h:268
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
STDMETHOD() QueryInterface(REFIID iid, void **ppvObject)
Definition: atlcom.h:160
unsigned char BYTE
Definition: xxhash.c:193
#define ERR(fmt,...)
Definition: debug.h:110
bool IsEmpty() const
Definition: atlsimpstr.h:379
IShellFolder * pshf
Definition: shlobj.h:1283
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define S_OK
Definition: intsafe.h:59
static VARIANTARG static DISPID
Definition: ordinal.c:49
#define RegOpenKeyEx
Definition: winreg.h:520
IUnknown ** end()
Definition: atlcom.h:1069
CComPtr< IShellFolderView > m_shellFolderView
UINT cbSize
Definition: shlobj.h:1282
LPCWSTR szPath
Definition: env.c:35
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:228
WCHAR szPath[MAX_PATH]
Definition: shellfind.h:36
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:561
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define E_NOTIMPL
Definition: ddrawi.h:99
CComPtr< IShellBrowser > m_shellBrowser
Definition: CFindFolder.h:69
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
STDMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidl)
unsigned int UINT
Definition: ndis.h:50
BOOL SearchHidden
Definition: shellfind.h:39
#define PAGE_READONLY
Definition: compat.h:127
static const TChar * StrStrN(const TChar *lpFirst, const TString &lpSrch, UINT cchMax)
CComPtr< IShellFolderView > m_shellFolderView
Definition: CFindFolder.h:68
STDMETHODIMP ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
#define CreateFileW
Definition: compat.h:409
#define WM_SEARCH_STOP
Definition: shellfind.h:30
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:331
const ITEMIDLIST_RELATIVE UNALIGNED * PCUIDLIST_RELATIVE
Definition: shtypes.idl:57
BOOL WINAPI PathMatchSpecW(LPCWSTR lpszPath, LPCWSTR lpszMask)
Definition: path.c:1943
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static HRESULT SHELL32_CoCreateInitSF(LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO *ppfti, LPCITEMIDLIST pidlChild, const GUID *clsid, REFIID riid, LPVOID *ppvOut)
Definition: CFindFolder.cpp:13
struct stdole::DISPPARAMS DISPPARAMS
STDMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
unsigned int ULONG
Definition: retypes.h:1
STDMETHODIMP MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid)
#define UNIMPLEMENTED
Definition: debug.h:115
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
STDMETHODIMP EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
Definition: dwarf.h:133
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define END_COM_MAP()
Definition: atlcom.h:552
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:982
#define SID_SShellBrowser
Definition: shlguid.h:125
CComPtr< IContextMenu > m_pInner
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define WM_SEARCH_UPDATE_STATUS
Definition: shellfind.h:32
LONG_PTR LRESULT
Definition: windef.h:209
LPWSTR WINAPI PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
Definition: path.c:189
LRESULT AddResult(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
#define UnmapViewOfFile
Definition: compat.h:412
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
GLuint64EXT * result
Definition: glext.h:11304
#define REG_DWORD
Definition: sdbapi.c:596
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static SERVICE_STATUS status
Definition: service.c:31
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
HANDLE hStopEvent
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:309
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static UINT SearchFile(LPCWSTR lpFilePath, _SearchData *pSearchData)
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
static FolderViewColumns g_ColumnDefs[]
Definition: CFindFolder.cpp:87
Definition: ps.c:97