13b9508e9SBrock Mammen /*
23b9508e9SBrock Mammen * PROJECT: ReactOS Search Shell Extension
33b9508e9SBrock Mammen * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
43b9508e9SBrock Mammen * PURPOSE: Search results folder
53b9508e9SBrock Mammen * COPYRIGHT: Copyright 2019 Brock Mammen
63b9508e9SBrock Mammen */
73b9508e9SBrock Mammen
8ccf9ce32SBrock Mammen #include "CFindFolder.h"
941d7b370SBrock Mammen #include <exdispid.h>
10ccf9ce32SBrock Mammen
11ccf9ce32SBrock Mammen WINE_DEFAULT_DEBUG_CHANNEL(shellfind);
12ccf9ce32SBrock Mammen
SHELL32_CoCreateInitSF(LPCITEMIDLIST pidlRoot,PERSIST_FOLDER_TARGET_INFO * ppfti,LPCITEMIDLIST pidlChild,const GUID * clsid,REFIID riid,LPVOID * ppvOut)13312b628fSBrock Mammen static HRESULT SHELL32_CoCreateInitSF(LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO* ppfti,
14312b628fSBrock Mammen LPCITEMIDLIST pidlChild, const GUID* clsid, REFIID riid, LPVOID *ppvOut)
15312b628fSBrock Mammen {
16312b628fSBrock Mammen HRESULT hr;
17312b628fSBrock Mammen CComPtr<IShellFolder> pShellFolder;
18312b628fSBrock Mammen
19312b628fSBrock Mammen hr = SHCoCreateInstance(NULL, clsid, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
20312b628fSBrock Mammen if (FAILED(hr))
21312b628fSBrock Mammen return hr;
22312b628fSBrock Mammen
23312b628fSBrock Mammen LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
24312b628fSBrock Mammen CComPtr<IPersistFolder> ppf;
25312b628fSBrock Mammen CComPtr<IPersistFolder3> ppf3;
26312b628fSBrock Mammen
27312b628fSBrock Mammen if (ppfti && SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3))))
28312b628fSBrock Mammen {
29312b628fSBrock Mammen ppf3->InitializeEx(NULL, pidlAbsolute, ppfti);
30312b628fSBrock Mammen }
31312b628fSBrock Mammen else if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &ppf))))
32312b628fSBrock Mammen {
33312b628fSBrock Mammen ppf->Initialize(pidlAbsolute);
34312b628fSBrock Mammen }
35312b628fSBrock Mammen ILFree (pidlAbsolute);
36312b628fSBrock Mammen
37312b628fSBrock Mammen return pShellFolder->QueryInterface(riid, ppvOut);
38312b628fSBrock Mammen }
39312b628fSBrock Mammen
_InsertMenuItemW(HMENU hMenu,UINT indexMenu,BOOL fByPosition,UINT wID,UINT fType,LPCWSTR dwTypeData,UINT fState)40312b628fSBrock Mammen static void WINAPI _InsertMenuItemW(
41312b628fSBrock Mammen HMENU hMenu,
42312b628fSBrock Mammen UINT indexMenu,
43312b628fSBrock Mammen BOOL fByPosition,
44312b628fSBrock Mammen UINT wID,
45312b628fSBrock Mammen UINT fType,
46312b628fSBrock Mammen LPCWSTR dwTypeData,
47312b628fSBrock Mammen UINT fState)
48312b628fSBrock Mammen {
49312b628fSBrock Mammen MENUITEMINFOW mii;
50312b628fSBrock Mammen WCHAR wszText[100];
51312b628fSBrock Mammen
52312b628fSBrock Mammen ZeroMemory(&mii, sizeof(mii));
53312b628fSBrock Mammen mii.cbSize = sizeof(mii);
54312b628fSBrock Mammen if (fType == MFT_SEPARATOR)
55312b628fSBrock Mammen mii.fMask = MIIM_ID | MIIM_TYPE;
56312b628fSBrock Mammen else if (fType == MFT_STRING)
57312b628fSBrock Mammen {
58312b628fSBrock Mammen mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
599b75b67eSBrock Mammen if (IS_INTRESOURCE(dwTypeData))
60312b628fSBrock Mammen {
61312b628fSBrock Mammen if (LoadStringW(_AtlBaseModule.GetResourceInstance(), LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
62312b628fSBrock Mammen mii.dwTypeData = wszText;
63312b628fSBrock Mammen else
64312b628fSBrock Mammen {
65312b628fSBrock Mammen ERR("failed to load string %p\n", dwTypeData);
66312b628fSBrock Mammen return;
67312b628fSBrock Mammen }
68312b628fSBrock Mammen }
69312b628fSBrock Mammen else
70312b628fSBrock Mammen mii.dwTypeData = (LPWSTR)dwTypeData;
71312b628fSBrock Mammen mii.fState = fState;
72312b628fSBrock Mammen }
73312b628fSBrock Mammen
74312b628fSBrock Mammen mii.wID = wID;
75312b628fSBrock Mammen mii.fType = fType;
76312b628fSBrock Mammen InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
77312b628fSBrock Mammen }
78312b628fSBrock Mammen
79ccf9ce32SBrock Mammen struct FolderViewColumns
80ccf9ce32SBrock Mammen {
816c6fd6d9SBrock Mammen int iResource;
82ccf9ce32SBrock Mammen DWORD dwDefaultState;
83ccf9ce32SBrock Mammen int fmt;
84ccf9ce32SBrock Mammen int cxChar;
85ccf9ce32SBrock Mammen };
86ccf9ce32SBrock Mammen
87ccf9ce32SBrock Mammen static FolderViewColumns g_ColumnDefs[] =
88ccf9ce32SBrock Mammen {
896c6fd6d9SBrock Mammen {IDS_COL_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
906c6fd6d9SBrock Mammen {IDS_COL_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
916c6fd6d9SBrock Mammen {IDS_COL_RELEVANCE, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 0}
92ccf9ce32SBrock Mammen };
93ccf9ce32SBrock Mammen
CFindFolder()946d6bc885SBrock Mammen CFindFolder::CFindFolder() :
956d6bc885SBrock Mammen m_hStopEvent(NULL)
966d6bc885SBrock Mammen {
976d6bc885SBrock Mammen }
986d6bc885SBrock Mammen
_ILCreate(LPCWSTR lpszPath)992f3db8d9SBrock Mammen static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath)
100666bf346SBrock Mammen {
1012f3db8d9SBrock Mammen CComHeapPtr<ITEMIDLIST> lpFSPidl(ILCreateFromPathW(lpszPath));
1027ac9fd9fSBrock Mammen if (!lpFSPidl)
1032f3db8d9SBrock Mammen {
1042f3db8d9SBrock Mammen ERR("Failed to create pidl from path\n");
1050311544bSBrock Mammen return NULL;
1062f3db8d9SBrock Mammen }
1072f3db8d9SBrock Mammen LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl);
1082f3db8d9SBrock Mammen
109a3ee648dSBrock Mammen int pathLen = (PathFindFileNameW(lpszPath) - lpszPath) * sizeof(WCHAR);
1102f3db8d9SBrock Mammen int cbData = sizeof(WORD) + pathLen + lpLastFSPidl->mkid.cb;
111666bf346SBrock Mammen LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(cbData + sizeof(WORD));
112666bf346SBrock Mammen if (!pidl)
113666bf346SBrock Mammen return NULL;
114666bf346SBrock Mammen
115666bf346SBrock Mammen LPBYTE p = (LPBYTE) pidl;
116666bf346SBrock Mammen *((WORD *) p) = cbData;
117666bf346SBrock Mammen p += sizeof(WORD);
118666bf346SBrock Mammen
119666bf346SBrock Mammen memcpy(p, lpszPath, pathLen);
120a3ee648dSBrock Mammen p += pathLen - sizeof(WCHAR);
121a3ee648dSBrock Mammen *((WCHAR *) p) = '\0';
122a3ee648dSBrock Mammen p += sizeof(WCHAR);
123666bf346SBrock Mammen
1242f3db8d9SBrock Mammen memcpy(p, lpLastFSPidl, lpLastFSPidl->mkid.cb);
1252f3db8d9SBrock Mammen p += lpLastFSPidl->mkid.cb;
126666bf346SBrock Mammen
127666bf346SBrock Mammen *((WORD *) p) = 0;
128666bf346SBrock Mammen
129666bf346SBrock Mammen return pidl;
130666bf346SBrock Mammen }
131666bf346SBrock Mammen
_ILGetPath(LPCITEMIDLIST pidl)132666bf346SBrock Mammen static LPCWSTR _ILGetPath(LPCITEMIDLIST pidl)
133666bf346SBrock Mammen {
134666bf346SBrock Mammen if (!pidl || !pidl->mkid.cb)
135666bf346SBrock Mammen return NULL;
136666bf346SBrock Mammen return (LPCWSTR) pidl->mkid.abID;
137666bf346SBrock Mammen }
138666bf346SBrock Mammen
_ILGetFSPidl(LPCITEMIDLIST pidl)139666bf346SBrock Mammen static LPCITEMIDLIST _ILGetFSPidl(LPCITEMIDLIST pidl)
140666bf346SBrock Mammen {
141666bf346SBrock Mammen if (!pidl || !pidl->mkid.cb)
142666bf346SBrock Mammen return pidl;
143666bf346SBrock Mammen return (LPCITEMIDLIST) ((LPBYTE) pidl->mkid.abID
144666bf346SBrock Mammen + ((wcslen((LPCWSTR) pidl->mkid.abID) + 1) * sizeof(WCHAR)));
145666bf346SBrock Mammen }
146666bf346SBrock Mammen
1472f3db8d9SBrock Mammen struct _SearchData
1482f3db8d9SBrock Mammen {
1492f3db8d9SBrock Mammen HWND hwnd;
1502f3db8d9SBrock Mammen HANDLE hStopEvent;
1518246cd4eSBrock Mammen CStringW szPath;
1528246cd4eSBrock Mammen CStringW szFileName;
1538246cd4eSBrock Mammen CStringA szQueryA;
1548246cd4eSBrock Mammen CStringW szQueryW;
1557376cdebSKatayama Hirofumi MZ CStringW szQueryU16BE;
1567376cdebSKatayama Hirofumi MZ CStringA szQueryU8;
157103c87d2SDoug Lyons BOOL SearchHidden;
1588246cd4eSBrock Mammen CComPtr<CFindFolder> pFindFolder;
1592f3db8d9SBrock Mammen };
1602f3db8d9SBrock Mammen
1618246cd4eSBrock Mammen template<typename TChar, typename TString, int (&StrNCmp)(const TChar *, const TChar *, size_t)>
StrStrN(const TChar * lpFirst,const TString & lpSrch,UINT cchMax)1628246cd4eSBrock Mammen static const TChar* StrStrN(const TChar *lpFirst, const TString &lpSrch, UINT cchMax)
1632f3db8d9SBrock Mammen {
1648246cd4eSBrock Mammen if (!lpFirst || lpSrch.IsEmpty() || !cchMax)
1652f3db8d9SBrock Mammen return NULL;
1662f3db8d9SBrock Mammen
1678246cd4eSBrock Mammen for (UINT i = cchMax; i > 0 && *lpFirst; i--, lpFirst++)
1682f3db8d9SBrock Mammen {
1698246cd4eSBrock Mammen if (!StrNCmp(lpFirst, lpSrch, lpSrch.GetLength()))
1708246cd4eSBrock Mammen return (const TChar*)lpFirst;
1712f3db8d9SBrock Mammen }
1722f3db8d9SBrock Mammen
1732f3db8d9SBrock Mammen return NULL;
1742f3db8d9SBrock Mammen }
1752f3db8d9SBrock Mammen
1767376cdebSKatayama Hirofumi MZ static inline BOOL
StrFindNIA(const CHAR * lpFirst,const CStringA & lpSrch,UINT cchMax)1777376cdebSKatayama Hirofumi MZ StrFindNIA(const CHAR *lpFirst, const CStringA &lpSrch, UINT cchMax)
1788246cd4eSBrock Mammen {
1797376cdebSKatayama Hirofumi MZ return StrStrN<CHAR, CStringA, _strnicmp>(lpFirst, lpSrch, cchMax) != NULL;
1808246cd4eSBrock Mammen }
1818246cd4eSBrock Mammen
1827376cdebSKatayama Hirofumi MZ static inline BOOL
StrFindNIW(const WCHAR * lpFirst,const CStringW & lpSrch,UINT cchMax)1837376cdebSKatayama Hirofumi MZ StrFindNIW(const WCHAR *lpFirst, const CStringW &lpSrch, UINT cchMax)
1848246cd4eSBrock Mammen {
1857376cdebSKatayama Hirofumi MZ return StrStrN<WCHAR, CStringW, _wcsnicmp>(lpFirst, lpSrch, cchMax) != NULL;
1868246cd4eSBrock Mammen }
1878246cd4eSBrock Mammen
188c8e3ef78SKatayama Hirofumi MZ /*
189c8e3ef78SKatayama Hirofumi MZ * The following code is borrowed from base/applications/cmdutils/more/more.c .
190c8e3ef78SKatayama Hirofumi MZ */
191c8e3ef78SKatayama Hirofumi MZ typedef enum
192c8e3ef78SKatayama Hirofumi MZ {
193c8e3ef78SKatayama Hirofumi MZ ENCODING_ANSI = 0,
194c8e3ef78SKatayama Hirofumi MZ ENCODING_UTF16LE = 1,
195c8e3ef78SKatayama Hirofumi MZ ENCODING_UTF16BE = 2,
196c8e3ef78SKatayama Hirofumi MZ ENCODING_UTF8 = 3
197c8e3ef78SKatayama Hirofumi MZ } ENCODING;
198c8e3ef78SKatayama Hirofumi MZ
199c8e3ef78SKatayama Hirofumi MZ static BOOL
IsDataUnicode(IN PVOID Buffer,IN DWORD BufferSize,OUT ENCODING * Encoding OPTIONAL,OUT PDWORD SkipBytes OPTIONAL)200c8e3ef78SKatayama Hirofumi MZ IsDataUnicode(
201c8e3ef78SKatayama Hirofumi MZ IN PVOID Buffer,
202c8e3ef78SKatayama Hirofumi MZ IN DWORD BufferSize,
203c8e3ef78SKatayama Hirofumi MZ OUT ENCODING* Encoding OPTIONAL,
204c8e3ef78SKatayama Hirofumi MZ OUT PDWORD SkipBytes OPTIONAL)
205c8e3ef78SKatayama Hirofumi MZ {
206c8e3ef78SKatayama Hirofumi MZ PBYTE pBytes = (PBYTE)Buffer;
207c8e3ef78SKatayama Hirofumi MZ ENCODING encFile = ENCODING_ANSI;
208c8e3ef78SKatayama Hirofumi MZ DWORD dwPos = 0;
209c8e3ef78SKatayama Hirofumi MZ
210c8e3ef78SKatayama Hirofumi MZ /*
211c8e3ef78SKatayama Hirofumi MZ * See http://archives.miloush.net/michkap/archive/2007/04/22/2239345.html
212c8e3ef78SKatayama Hirofumi MZ * for more details about the algorithm and the pitfalls behind it.
213c8e3ef78SKatayama Hirofumi MZ * Of course it would be actually great to make a nice function that
214c8e3ef78SKatayama Hirofumi MZ * would work, once and for all, and put it into a library.
215c8e3ef78SKatayama Hirofumi MZ */
216c8e3ef78SKatayama Hirofumi MZ
217c8e3ef78SKatayama Hirofumi MZ /* Look for Byte Order Marks */
218c8e3ef78SKatayama Hirofumi MZ if ((BufferSize >= 2) && (pBytes[0] == 0xFF) && (pBytes[1] == 0xFE))
219c8e3ef78SKatayama Hirofumi MZ {
220c8e3ef78SKatayama Hirofumi MZ encFile = ENCODING_UTF16LE;
221c8e3ef78SKatayama Hirofumi MZ dwPos = 2;
222c8e3ef78SKatayama Hirofumi MZ }
223c8e3ef78SKatayama Hirofumi MZ else if ((BufferSize >= 2) && (pBytes[0] == 0xFE) && (pBytes[1] == 0xFF))
224c8e3ef78SKatayama Hirofumi MZ {
225c8e3ef78SKatayama Hirofumi MZ encFile = ENCODING_UTF16BE;
226c8e3ef78SKatayama Hirofumi MZ dwPos = 2;
227c8e3ef78SKatayama Hirofumi MZ }
228c8e3ef78SKatayama Hirofumi MZ else if ((BufferSize >= 3) && (pBytes[0] == 0xEF) && (pBytes[1] == 0xBB) && (pBytes[2] == 0xBF))
229c8e3ef78SKatayama Hirofumi MZ {
230c8e3ef78SKatayama Hirofumi MZ encFile = ENCODING_UTF8;
231c8e3ef78SKatayama Hirofumi MZ dwPos = 3;
232c8e3ef78SKatayama Hirofumi MZ }
233c8e3ef78SKatayama Hirofumi MZ else
234c8e3ef78SKatayama Hirofumi MZ {
235c8e3ef78SKatayama Hirofumi MZ /*
236c8e3ef78SKatayama Hirofumi MZ * Try using statistical analysis. Do not rely on the return value of
237c8e3ef78SKatayama Hirofumi MZ * IsTextUnicode as we can get FALSE even if the text is in UTF-16 BE
238c8e3ef78SKatayama Hirofumi MZ * (i.e. we have some of the IS_TEXT_UNICODE_REVERSE_MASK bits set).
239c8e3ef78SKatayama Hirofumi MZ * Instead, set all the tests we want to perform, then just check
240c8e3ef78SKatayama Hirofumi MZ * the passed tests and try to deduce the string properties.
241c8e3ef78SKatayama Hirofumi MZ */
242c8e3ef78SKatayama Hirofumi MZ
243c8e3ef78SKatayama Hirofumi MZ /*
244c8e3ef78SKatayama Hirofumi MZ * This mask contains the 3 highest bits from IS_TEXT_UNICODE_NOT_ASCII_MASK
245c8e3ef78SKatayama Hirofumi MZ * and the 1st highest bit from IS_TEXT_UNICODE_NOT_UNICODE_MASK.
246c8e3ef78SKatayama Hirofumi MZ */
247c8e3ef78SKatayama Hirofumi MZ #define IS_TEXT_UNKNOWN_FLAGS_MASK ((7 << 13) | (1 << 11))
248c8e3ef78SKatayama Hirofumi MZ
249c8e3ef78SKatayama Hirofumi MZ /* Flag out the unknown flags here, the passed tests will not have them either */
250c8e3ef78SKatayama Hirofumi MZ INT Tests = (IS_TEXT_UNICODE_NOT_ASCII_MASK |
251c8e3ef78SKatayama Hirofumi MZ IS_TEXT_UNICODE_NOT_UNICODE_MASK |
252c8e3ef78SKatayama Hirofumi MZ IS_TEXT_UNICODE_REVERSE_MASK | IS_TEXT_UNICODE_UNICODE_MASK)
253c8e3ef78SKatayama Hirofumi MZ & ~IS_TEXT_UNKNOWN_FLAGS_MASK;
254c8e3ef78SKatayama Hirofumi MZ INT Results;
255c8e3ef78SKatayama Hirofumi MZ
256c8e3ef78SKatayama Hirofumi MZ IsTextUnicode(Buffer, BufferSize, &Tests);
257c8e3ef78SKatayama Hirofumi MZ Results = Tests;
258c8e3ef78SKatayama Hirofumi MZ
259c8e3ef78SKatayama Hirofumi MZ /*
260c8e3ef78SKatayama Hirofumi MZ * As the IS_TEXT_UNICODE_NULL_BYTES or IS_TEXT_UNICODE_ILLEGAL_CHARS
261c8e3ef78SKatayama Hirofumi MZ * flags are expected to be potentially present in the result without
262c8e3ef78SKatayama Hirofumi MZ * modifying our expectations, filter them out now.
263c8e3ef78SKatayama Hirofumi MZ */
264c8e3ef78SKatayama Hirofumi MZ Results &= ~(IS_TEXT_UNICODE_NULL_BYTES | IS_TEXT_UNICODE_ILLEGAL_CHARS);
265c8e3ef78SKatayama Hirofumi MZ
266c8e3ef78SKatayama Hirofumi MZ /*
267c8e3ef78SKatayama Hirofumi MZ * NOTE: The flags IS_TEXT_UNICODE_ASCII16 and
268c8e3ef78SKatayama Hirofumi MZ * IS_TEXT_UNICODE_REVERSE_ASCII16 are not reliable.
269c8e3ef78SKatayama Hirofumi MZ *
270c8e3ef78SKatayama Hirofumi MZ * NOTE2: Check for potential "bush hid the facts" effect by also
271c8e3ef78SKatayama Hirofumi MZ * checking the original results (in 'Tests') for the absence of
272c8e3ef78SKatayama Hirofumi MZ * the IS_TEXT_UNICODE_NULL_BYTES flag, as we may presumably expect
273c8e3ef78SKatayama Hirofumi MZ * that in UTF-16 text there will be at some point some NULL bytes.
274c8e3ef78SKatayama Hirofumi MZ * If not, fall back to ANSI. This shows the limitations of using the
275c8e3ef78SKatayama Hirofumi MZ * IsTextUnicode API to perform such tests, and the usage of a more
276c8e3ef78SKatayama Hirofumi MZ * improved encoding detection algorithm would be really welcome.
277c8e3ef78SKatayama Hirofumi MZ */
278c8e3ef78SKatayama Hirofumi MZ if (!(Results & IS_TEXT_UNICODE_NOT_UNICODE_MASK) &&
279c8e3ef78SKatayama Hirofumi MZ !(Results & IS_TEXT_UNICODE_REVERSE_MASK) &&
280c8e3ef78SKatayama Hirofumi MZ (Results & IS_TEXT_UNICODE_UNICODE_MASK) &&
281c8e3ef78SKatayama Hirofumi MZ (Tests & IS_TEXT_UNICODE_NULL_BYTES))
282c8e3ef78SKatayama Hirofumi MZ {
283c8e3ef78SKatayama Hirofumi MZ encFile = ENCODING_UTF16LE;
284c8e3ef78SKatayama Hirofumi MZ dwPos = (Results & IS_TEXT_UNICODE_SIGNATURE) ? 2 : 0;
285c8e3ef78SKatayama Hirofumi MZ }
286c8e3ef78SKatayama Hirofumi MZ else
287c8e3ef78SKatayama Hirofumi MZ if (!(Results & IS_TEXT_UNICODE_NOT_UNICODE_MASK) &&
288c8e3ef78SKatayama Hirofumi MZ !(Results & IS_TEXT_UNICODE_UNICODE_MASK) &&
289c8e3ef78SKatayama Hirofumi MZ (Results & IS_TEXT_UNICODE_REVERSE_MASK) &&
290c8e3ef78SKatayama Hirofumi MZ (Tests & IS_TEXT_UNICODE_NULL_BYTES))
291c8e3ef78SKatayama Hirofumi MZ {
292c8e3ef78SKatayama Hirofumi MZ encFile = ENCODING_UTF16BE;
293c8e3ef78SKatayama Hirofumi MZ dwPos = (Results & IS_TEXT_UNICODE_REVERSE_SIGNATURE) ? 2 : 0;
294c8e3ef78SKatayama Hirofumi MZ }
295c8e3ef78SKatayama Hirofumi MZ else
296c8e3ef78SKatayama Hirofumi MZ {
297c8e3ef78SKatayama Hirofumi MZ /*
298c8e3ef78SKatayama Hirofumi MZ * Either 'Results' has neither of those masks set, as it can be
299c8e3ef78SKatayama Hirofumi MZ * the case for UTF-8 text (or ANSI), or it has both as can be the
300c8e3ef78SKatayama Hirofumi MZ * case when analysing pure binary data chunk. This is therefore
301c8e3ef78SKatayama Hirofumi MZ * invalid and we fall back to ANSI encoding.
302c8e3ef78SKatayama Hirofumi MZ * FIXME: In case of failure, assume ANSI (as long as we do not have
303c8e3ef78SKatayama Hirofumi MZ * correct tests for UTF8, otherwise we should do them, and at the
304c8e3ef78SKatayama Hirofumi MZ * very end, assume ANSI).
305c8e3ef78SKatayama Hirofumi MZ */
306c8e3ef78SKatayama Hirofumi MZ encFile = ENCODING_ANSI; // ENCODING_UTF8;
307c8e3ef78SKatayama Hirofumi MZ dwPos = 0;
308c8e3ef78SKatayama Hirofumi MZ }
309c8e3ef78SKatayama Hirofumi MZ }
310c8e3ef78SKatayama Hirofumi MZ
311c8e3ef78SKatayama Hirofumi MZ if (Encoding)
312c8e3ef78SKatayama Hirofumi MZ *Encoding = encFile;
313c8e3ef78SKatayama Hirofumi MZ if (SkipBytes)
314c8e3ef78SKatayama Hirofumi MZ *SkipBytes = dwPos;
315c8e3ef78SKatayama Hirofumi MZ
316c8e3ef78SKatayama Hirofumi MZ return (encFile != ENCODING_ANSI);
317c8e3ef78SKatayama Hirofumi MZ }
318c8e3ef78SKatayama Hirofumi MZ
SearchFile(LPCWSTR lpFilePath,_SearchData * pSearchData)3197376cdebSKatayama Hirofumi MZ static BOOL SearchFile(LPCWSTR lpFilePath, _SearchData *pSearchData)
3202f3db8d9SBrock Mammen {
3212f3db8d9SBrock Mammen HANDLE hFile = CreateFileW(lpFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
3222f3db8d9SBrock Mammen if (hFile == INVALID_HANDLE_VALUE)
3237376cdebSKatayama Hirofumi MZ return FALSE;
3242f3db8d9SBrock Mammen
3257376cdebSKatayama Hirofumi MZ // FIXME: support large file
3262f3db8d9SBrock Mammen DWORD size = GetFileSize(hFile, NULL);
3277376cdebSKatayama Hirofumi MZ if (size == 0 || size == INVALID_FILE_SIZE)
3287376cdebSKatayama Hirofumi MZ {
3297376cdebSKatayama Hirofumi MZ CloseHandle(hFile);
3307376cdebSKatayama Hirofumi MZ return FALSE;
3317376cdebSKatayama Hirofumi MZ }
3327376cdebSKatayama Hirofumi MZ
3337376cdebSKatayama Hirofumi MZ HANDLE hFileMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, size, NULL);
3342f3db8d9SBrock Mammen CloseHandle(hFile);
3352f3db8d9SBrock Mammen if (hFileMap == INVALID_HANDLE_VALUE)
3367376cdebSKatayama Hirofumi MZ return FALSE;
3372f3db8d9SBrock Mammen
3387376cdebSKatayama Hirofumi MZ LPBYTE pbContents = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, size);
3392f3db8d9SBrock Mammen CloseHandle(hFileMap);
3407376cdebSKatayama Hirofumi MZ if (!pbContents)
3417376cdebSKatayama Hirofumi MZ return FALSE;
3422f3db8d9SBrock Mammen
343c8e3ef78SKatayama Hirofumi MZ ENCODING encoding;
344c8e3ef78SKatayama Hirofumi MZ IsDataUnicode(pbContents, size, &encoding, NULL);
345c8e3ef78SKatayama Hirofumi MZ
3467376cdebSKatayama Hirofumi MZ BOOL bFound;
347c8e3ef78SKatayama Hirofumi MZ switch (encoding)
3482f3db8d9SBrock Mammen {
349c8e3ef78SKatayama Hirofumi MZ case ENCODING_UTF16LE:
3507376cdebSKatayama Hirofumi MZ // UTF-16
3517376cdebSKatayama Hirofumi MZ bFound = StrFindNIW((LPCWSTR)pbContents, pSearchData->szQueryW, size / sizeof(WCHAR));
352c8e3ef78SKatayama Hirofumi MZ break;
353c8e3ef78SKatayama Hirofumi MZ case ENCODING_UTF16BE:
3547376cdebSKatayama Hirofumi MZ // UTF-16 BE
3557376cdebSKatayama Hirofumi MZ bFound = StrFindNIW((LPCWSTR)pbContents, pSearchData->szQueryU16BE, size / sizeof(WCHAR));
356c8e3ef78SKatayama Hirofumi MZ break;
357c8e3ef78SKatayama Hirofumi MZ case ENCODING_UTF8:
3587376cdebSKatayama Hirofumi MZ // UTF-8
3597376cdebSKatayama Hirofumi MZ bFound = StrFindNIA((LPCSTR)pbContents, pSearchData->szQueryU8, size / sizeof(CHAR));
360c8e3ef78SKatayama Hirofumi MZ break;
361c8e3ef78SKatayama Hirofumi MZ case ENCODING_ANSI:
362c8e3ef78SKatayama Hirofumi MZ default:
363c8e3ef78SKatayama Hirofumi MZ // ANSI or UTF-8 without BOM
3647376cdebSKatayama Hirofumi MZ bFound = StrFindNIA((LPCSTR)pbContents, pSearchData->szQueryA, size / sizeof(CHAR));
365c8e3ef78SKatayama Hirofumi MZ if (!bFound && pSearchData->szQueryA != pSearchData->szQueryU8)
366c8e3ef78SKatayama Hirofumi MZ bFound = StrFindNIA((LPCSTR)pbContents, pSearchData->szQueryU8, size / sizeof(CHAR));
367c8e3ef78SKatayama Hirofumi MZ break;
3682f3db8d9SBrock Mammen }
3692f3db8d9SBrock Mammen
3707376cdebSKatayama Hirofumi MZ UnmapViewOfFile(pbContents);
3717376cdebSKatayama Hirofumi MZ return bFound;
3722f3db8d9SBrock Mammen }
3732f3db8d9SBrock Mammen
FileNameMatch(LPCWSTR FindDataFileName,_SearchData * pSearchData)374103c87d2SDoug Lyons static BOOL FileNameMatch(LPCWSTR FindDataFileName, _SearchData *pSearchData)
375103c87d2SDoug Lyons {
376103c87d2SDoug Lyons if (pSearchData->szFileName.IsEmpty() || PathMatchSpecW(FindDataFileName, pSearchData->szFileName))
377103c87d2SDoug Lyons {
378103c87d2SDoug Lyons return TRUE;
379103c87d2SDoug Lyons }
380103c87d2SDoug Lyons return FALSE;
381103c87d2SDoug Lyons }
382103c87d2SDoug Lyons
ContentsMatch(LPCWSTR szPath,_SearchData * pSearchData)383103c87d2SDoug Lyons static BOOL ContentsMatch(LPCWSTR szPath, _SearchData *pSearchData)
384103c87d2SDoug Lyons {
385103c87d2SDoug Lyons if (pSearchData->szQueryA.IsEmpty() || SearchFile(szPath, pSearchData))
386103c87d2SDoug Lyons {
387103c87d2SDoug Lyons return TRUE;
388103c87d2SDoug Lyons }
389103c87d2SDoug Lyons return FALSE;
390103c87d2SDoug Lyons }
391103c87d2SDoug Lyons
AttribHiddenMatch(DWORD FileAttributes,_SearchData * pSearchData)392103c87d2SDoug Lyons static BOOL AttribHiddenMatch(DWORD FileAttributes, _SearchData *pSearchData)
393103c87d2SDoug Lyons {
394103c87d2SDoug Lyons if (!(FileAttributes & FILE_ATTRIBUTE_HIDDEN) || (pSearchData->SearchHidden))
395103c87d2SDoug Lyons {
396103c87d2SDoug Lyons return TRUE;
397103c87d2SDoug Lyons }
398103c87d2SDoug Lyons return FALSE;
399103c87d2SDoug Lyons }
400103c87d2SDoug Lyons
RecursiveFind(LPCWSTR lpPath,_SearchData * pSearchData)401c46d6036SBrock Mammen static UINT RecursiveFind(LPCWSTR lpPath, _SearchData *pSearchData)
4022f3db8d9SBrock Mammen {
4032f3db8d9SBrock Mammen if (WaitForSingleObject(pSearchData->hStopEvent, 0) != WAIT_TIMEOUT)
404c46d6036SBrock Mammen return 0;
4052f3db8d9SBrock Mammen
4062f3db8d9SBrock Mammen WCHAR szPath[MAX_PATH];
4072f3db8d9SBrock Mammen WIN32_FIND_DATAW FindData;
4082f3db8d9SBrock Mammen HANDLE hFindFile;
4092f3db8d9SBrock Mammen BOOL bMoreFiles = TRUE;
410c46d6036SBrock Mammen UINT uTotalFound = 0;
4112f3db8d9SBrock Mammen
4127376cdebSKatayama Hirofumi MZ PathCombineW(szPath, lpPath, L"*");
4132f3db8d9SBrock Mammen
4142f3db8d9SBrock Mammen for (hFindFile = FindFirstFileW(szPath, &FindData);
4152f3db8d9SBrock Mammen bMoreFiles && hFindFile != INVALID_HANDLE_VALUE;
4162f3db8d9SBrock Mammen bMoreFiles = FindNextFileW(hFindFile, &FindData))
4172f3db8d9SBrock Mammen {
4187376cdebSKatayama Hirofumi MZ #define IS_DOTS(psz) ((psz)[0] == L'.' && ((psz)[1] == 0 || ((psz)[1] == L'.' && (psz)[2] == 0)))
4197376cdebSKatayama Hirofumi MZ if (IS_DOTS(FindData.cFileName))
4202f3db8d9SBrock Mammen continue;
4212f3db8d9SBrock Mammen
4222f3db8d9SBrock Mammen PathCombineW(szPath, lpPath, FindData.cFileName);
4232f3db8d9SBrock Mammen
4242f3db8d9SBrock Mammen if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
4252f3db8d9SBrock Mammen {
426c46d6036SBrock Mammen CStringW status;
4272dd4f871SKatayama Hirofumi MZ if (pSearchData->szQueryW.IsEmpty() &&
4282dd4f871SKatayama Hirofumi MZ FileNameMatch(FindData.cFileName, pSearchData) &&
4292dd4f871SKatayama Hirofumi MZ AttribHiddenMatch(FindData.dwFileAttributes, pSearchData))
430b6b7bda4SDoug Lyons {
4310fbf4fb8SKatayama Hirofumi MZ LPWSTR pszPathDup;
4320fbf4fb8SKatayama Hirofumi MZ SHStrDupW(szPath, &pszPathDup);
4330fbf4fb8SKatayama Hirofumi MZ PostMessageW(pSearchData->hwnd, WM_SEARCH_ADD_RESULT, 0, (LPARAM)pszPathDup);
434b6b7bda4SDoug Lyons uTotalFound++;
435b6b7bda4SDoug Lyons }
436c46d6036SBrock Mammen status.Format(IDS_SEARCH_FOLDER, FindData.cFileName);
4370fbf4fb8SKatayama Hirofumi MZ LPWSTR pszStatusDup;
4380fbf4fb8SKatayama Hirofumi MZ SHStrDupW(status.GetBuffer(), &pszStatusDup);
4390fbf4fb8SKatayama Hirofumi MZ PostMessageW(pSearchData->hwnd, WM_SEARCH_UPDATE_STATUS, 0, (LPARAM)pszStatusDup);
4402f3db8d9SBrock Mammen
441c46d6036SBrock Mammen uTotalFound += RecursiveFind(szPath, pSearchData);
4422f3db8d9SBrock Mammen }
443103c87d2SDoug Lyons else if (FileNameMatch(FindData.cFileName, pSearchData)
444103c87d2SDoug Lyons && AttribHiddenMatch(FindData.dwFileAttributes, pSearchData)
445103c87d2SDoug Lyons && ContentsMatch(szPath, pSearchData))
4462f3db8d9SBrock Mammen {
4478246cd4eSBrock Mammen uTotalFound++;
4480fbf4fb8SKatayama Hirofumi MZ LPWSTR pszPathDup;
4490fbf4fb8SKatayama Hirofumi MZ SHStrDupW(szPath, &pszPathDup);
4500fbf4fb8SKatayama Hirofumi MZ PostMessageW(pSearchData->hwnd, WM_SEARCH_ADD_RESULT, 0, (LPARAM)pszPathDup);
4512f3db8d9SBrock Mammen }
4522f3db8d9SBrock Mammen }
4532f3db8d9SBrock Mammen
4542f3db8d9SBrock Mammen if (hFindFile != INVALID_HANDLE_VALUE)
4552f3db8d9SBrock Mammen FindClose(hFindFile);
456c46d6036SBrock Mammen
457c46d6036SBrock Mammen return uTotalFound;
4582f3db8d9SBrock Mammen }
4592f3db8d9SBrock Mammen
SearchThreadProc(LPVOID lpParameter)4608246cd4eSBrock Mammen DWORD WINAPI CFindFolder::SearchThreadProc(LPVOID lpParameter)
4612f3db8d9SBrock Mammen {
4622f3db8d9SBrock Mammen _SearchData *data = static_cast<_SearchData*>(lpParameter);
4632f3db8d9SBrock Mammen
4640aa2e82cSKatayama Hirofumi MZ HRESULT hrCoInit = CoInitializeEx(NULL, COINIT_MULTITHREADED);
4650aa2e82cSKatayama Hirofumi MZ
46641d7b370SBrock Mammen data->pFindFolder->NotifyConnections(DISPID_SEARCHSTART);
46741d7b370SBrock Mammen
468c46d6036SBrock Mammen UINT uTotalFound = RecursiveFind(data->szPath, data);
4692f3db8d9SBrock Mammen
47041d7b370SBrock Mammen data->pFindFolder->NotifyConnections(DISPID_SEARCHCOMPLETE);
47141d7b370SBrock Mammen
472c46d6036SBrock Mammen CStringW status;
473c46d6036SBrock Mammen status.Format(IDS_SEARCH_FILES_FOUND, uTotalFound);
4740fbf4fb8SKatayama Hirofumi MZ LPWSTR pszStatusDup;
4750fbf4fb8SKatayama Hirofumi MZ SHStrDupW(status.GetBuffer(), &pszStatusDup);
4760fbf4fb8SKatayama Hirofumi MZ ::PostMessageW(data->hwnd, WM_SEARCH_UPDATE_STATUS, 0, (LPARAM)pszStatusDup);
477fe5c76a0SBrock Mammen ::SendMessageW(data->hwnd, WM_SEARCH_STOP, 0, 0);
478c46d6036SBrock Mammen
479fe5c76a0SBrock Mammen CloseHandle(data->hStopEvent);
480c46d6036SBrock Mammen delete data;
4812f3db8d9SBrock Mammen
4820aa2e82cSKatayama Hirofumi MZ if (SUCCEEDED(hrCoInit))
4830aa2e82cSKatayama Hirofumi MZ CoUninitialize();
4840aa2e82cSKatayama Hirofumi MZ
4852f3db8d9SBrock Mammen return 0;
4862f3db8d9SBrock Mammen }
4872f3db8d9SBrock Mammen
NotifyConnections(DISPID id)48841d7b370SBrock Mammen void CFindFolder::NotifyConnections(DISPID id)
48941d7b370SBrock Mammen {
49041d7b370SBrock Mammen DISPPARAMS dispatchParams = {0};
49141d7b370SBrock Mammen CComDynamicUnkArray &subscribers =
49241d7b370SBrock Mammen IConnectionPointImpl<CFindFolder, &DIID_DSearchCommandEvents>::m_vec;
49341d7b370SBrock Mammen for (IUnknown** pSubscriber = subscribers.begin(); pSubscriber < subscribers.end(); pSubscriber++)
49441d7b370SBrock Mammen {
49541d7b370SBrock Mammen if (!*pSubscriber)
49641d7b370SBrock Mammen continue;
49741d7b370SBrock Mammen
49841d7b370SBrock Mammen CComPtr<IDispatch> pDispatch;
49941d7b370SBrock Mammen HRESULT hResult = (*pSubscriber)->QueryInterface(IID_PPV_ARG(IDispatch, &pDispatch));
50041d7b370SBrock Mammen if (!FAILED_UNEXPECTEDLY(hResult))
50141d7b370SBrock Mammen pDispatch->Invoke(id, GUID_NULL, 0, DISPATCH_METHOD, &dispatchParams, NULL, NULL, NULL);
50241d7b370SBrock Mammen }
50341d7b370SBrock Mammen }
50441d7b370SBrock Mammen
StartSearch(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)5052f3db8d9SBrock Mammen LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
506666bf346SBrock Mammen {
507103c87d2SDoug Lyons HKEY hkey;
508103c87d2SDoug Lyons DWORD size = sizeof(DWORD);
509103c87d2SDoug Lyons DWORD result;
510103c87d2SDoug Lyons DWORD SearchHiddenValue = 0;
511103c87d2SDoug Lyons
512666bf346SBrock Mammen if (!lParam)
513666bf346SBrock Mammen return 0;
514666bf346SBrock Mammen
5152f3db8d9SBrock Mammen // Clear all previous search results
516666bf346SBrock Mammen UINT uItemIndex;
5172f3db8d9SBrock Mammen m_shellFolderView->RemoveObject(NULL, &uItemIndex);
518666bf346SBrock Mammen
5192f3db8d9SBrock Mammen _SearchData* pSearchData = new _SearchData();
5202f3db8d9SBrock Mammen pSearchData->pFindFolder = this;
5212f3db8d9SBrock Mammen pSearchData->hwnd = m_hWnd;
5228246cd4eSBrock Mammen
5238246cd4eSBrock Mammen SearchStart *pSearchParams = (SearchStart *) lParam;
5248246cd4eSBrock Mammen pSearchData->szPath = pSearchParams->szPath;
5258246cd4eSBrock Mammen pSearchData->szFileName = pSearchParams->szFileName;
5268246cd4eSBrock Mammen pSearchData->szQueryA = pSearchParams->szQuery;
5278246cd4eSBrock Mammen pSearchData->szQueryW = pSearchParams->szQuery;
5287376cdebSKatayama Hirofumi MZ
5297376cdebSKatayama Hirofumi MZ // UTF-16 BE
5307376cdebSKatayama Hirofumi MZ {
5317376cdebSKatayama Hirofumi MZ CStringW utf16 = pSearchData->szQueryW;
5327376cdebSKatayama Hirofumi MZ LPWSTR psz = utf16.GetBuffer();
5337376cdebSKatayama Hirofumi MZ for (SIZE_T i = 0; psz[i]; ++i)
5347376cdebSKatayama Hirofumi MZ {
5357376cdebSKatayama Hirofumi MZ psz[i] = MAKEWORD(HIBYTE(psz[i]), LOBYTE(psz[i]));
5367376cdebSKatayama Hirofumi MZ }
5377376cdebSKatayama Hirofumi MZ utf16.ReleaseBuffer();
5387376cdebSKatayama Hirofumi MZ pSearchData->szQueryU16BE = utf16;
5397376cdebSKatayama Hirofumi MZ }
5407376cdebSKatayama Hirofumi MZ
5417376cdebSKatayama Hirofumi MZ // UTF-8
5427376cdebSKatayama Hirofumi MZ {
5437376cdebSKatayama Hirofumi MZ CStringA utf8;
5447376cdebSKatayama Hirofumi MZ INT cch = WideCharToMultiByte(CP_UTF8, 0, pSearchData->szQueryW, -1, NULL, 0, NULL, NULL);
5457376cdebSKatayama Hirofumi MZ if (cch > 0)
5467376cdebSKatayama Hirofumi MZ {
5477376cdebSKatayama Hirofumi MZ LPSTR psz = utf8.GetBuffer(cch);
5487376cdebSKatayama Hirofumi MZ WideCharToMultiByte(CP_UTF8, 0, pSearchData->szQueryW, -1, psz, cch, NULL, NULL);
5497376cdebSKatayama Hirofumi MZ utf8.ReleaseBuffer();
5507376cdebSKatayama Hirofumi MZ pSearchData->szQueryU8 = utf8;
5517376cdebSKatayama Hirofumi MZ }
5527376cdebSKatayama Hirofumi MZ else
5537376cdebSKatayama Hirofumi MZ {
5547376cdebSKatayama Hirofumi MZ pSearchData->szQueryU8 = pSearchData->szQueryA;
5557376cdebSKatayama Hirofumi MZ }
5567376cdebSKatayama Hirofumi MZ }
5577376cdebSKatayama Hirofumi MZ
558103c87d2SDoug Lyons pSearchData->SearchHidden = pSearchParams->SearchHidden;
5598246cd4eSBrock Mammen SHFree(pSearchParams);
5608246cd4eSBrock Mammen
561103c87d2SDoug Lyons TRACE("pSearchParams->SearchHidden is '%d'.\n", pSearchData->SearchHidden);
562103c87d2SDoug Lyons
563103c87d2SDoug Lyons if (pSearchData->SearchHidden)
564103c87d2SDoug Lyons SearchHiddenValue = 1;
565103c87d2SDoug Lyons else
566103c87d2SDoug Lyons SearchHiddenValue = 0;
567103c87d2SDoug Lyons
568103c87d2SDoug Lyons /* Placing the code to save the changed settings to the registry here has the effect of not saving any changes */
569103c87d2SDoug Lyons /* to the registry unless the user clicks on the "Search" button. This is the same as what we see in Windows. */
570103c87d2SDoug Lyons result = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", 0, KEY_SET_VALUE, &hkey);
571103c87d2SDoug Lyons if (result == ERROR_SUCCESS)
572103c87d2SDoug Lyons {
573103c87d2SDoug Lyons if (RegSetValueExW(hkey, L"SearchHidden", NULL, REG_DWORD, (const BYTE*)&SearchHiddenValue, size) == ERROR_SUCCESS)
574103c87d2SDoug Lyons {
575103c87d2SDoug Lyons TRACE("SearchHidden is '%d'.\n", SearchHiddenValue);
576103c87d2SDoug Lyons }
577103c87d2SDoug Lyons else
578103c87d2SDoug Lyons {
579103c87d2SDoug Lyons ERR("RegSetValueEx for \"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SearchHidden\" Failed.\n");
580103c87d2SDoug Lyons }
581103c87d2SDoug Lyons RegCloseKey(hkey);
582103c87d2SDoug Lyons }
583103c87d2SDoug Lyons else
584103c87d2SDoug Lyons {
585103c87d2SDoug Lyons ERR("RegOpenKey for \"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\" Failed.\n");
586103c87d2SDoug Lyons }
587103c87d2SDoug Lyons
5882f3db8d9SBrock Mammen if (m_hStopEvent)
5892f3db8d9SBrock Mammen SetEvent(m_hStopEvent);
5902f3db8d9SBrock Mammen pSearchData->hStopEvent = m_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
5912f3db8d9SBrock Mammen
5928246cd4eSBrock Mammen if (!SHCreateThread(SearchThreadProc, pSearchData, NULL, NULL))
5932f3db8d9SBrock Mammen {
5942f3db8d9SBrock Mammen SHFree(pSearchData);
5950311544bSBrock Mammen return 0;
5962f3db8d9SBrock Mammen }
5972f3db8d9SBrock Mammen
5980311544bSBrock Mammen return 0;
5992f3db8d9SBrock Mammen }
6002f3db8d9SBrock Mammen
StopSearch(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)60141f9ad12SBrock Mammen LRESULT CFindFolder::StopSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
60241f9ad12SBrock Mammen {
60341f9ad12SBrock Mammen if (m_hStopEvent)
60441f9ad12SBrock Mammen {
60541f9ad12SBrock Mammen SetEvent(m_hStopEvent);
60641f9ad12SBrock Mammen m_hStopEvent = NULL;
60741f9ad12SBrock Mammen }
60841f9ad12SBrock Mammen return 0;
60941f9ad12SBrock Mammen }
61041f9ad12SBrock Mammen
AddResult(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)6112f3db8d9SBrock Mammen LRESULT CFindFolder::AddResult(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
6122f3db8d9SBrock Mammen {
6132f3db8d9SBrock Mammen if (!lParam)
6142f3db8d9SBrock Mammen return 0;
6152f3db8d9SBrock Mammen
6162f3db8d9SBrock Mammen CComHeapPtr<WCHAR> lpPath((LPWSTR) lParam);
6172f3db8d9SBrock Mammen
6182f3db8d9SBrock Mammen CComHeapPtr<ITEMIDLIST> lpSearchPidl(_ILCreate(lpPath));
6192f3db8d9SBrock Mammen if (lpSearchPidl)
6202f3db8d9SBrock Mammen {
6212f3db8d9SBrock Mammen UINT uItemIndex;
6222f3db8d9SBrock Mammen m_shellFolderView->AddObject(lpSearchPidl, &uItemIndex);
6232f3db8d9SBrock Mammen }
6242f3db8d9SBrock Mammen
6252f3db8d9SBrock Mammen return 0;
626666bf346SBrock Mammen }
627666bf346SBrock Mammen
UpdateStatus(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)62804fcbe32SBrock Mammen LRESULT CFindFolder::UpdateStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
62904fcbe32SBrock Mammen {
630c46d6036SBrock Mammen CComHeapPtr<WCHAR> status((LPWSTR) lParam);
63104fcbe32SBrock Mammen if (m_shellBrowser)
63204fcbe32SBrock Mammen {
633c46d6036SBrock Mammen m_shellBrowser->SetStatusTextSB(status);
63404fcbe32SBrock Mammen }
63504fcbe32SBrock Mammen
6360311544bSBrock Mammen return 0;
63704fcbe32SBrock Mammen }
63804fcbe32SBrock Mammen
639ccf9ce32SBrock Mammen // *** IShellFolder2 methods ***
GetDefaultSearchGUID(GUID * pguid)640ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetDefaultSearchGUID(GUID *pguid)
641ccf9ce32SBrock Mammen {
642ccf9ce32SBrock Mammen UNIMPLEMENTED;
643ccf9ce32SBrock Mammen return E_NOTIMPL;
644ccf9ce32SBrock Mammen }
645ccf9ce32SBrock Mammen
EnumSearches(IEnumExtraSearch ** ppenum)646ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::EnumSearches(IEnumExtraSearch **ppenum)
647ccf9ce32SBrock Mammen {
648ccf9ce32SBrock Mammen UNIMPLEMENTED;
649ccf9ce32SBrock Mammen return E_NOTIMPL;
650ccf9ce32SBrock Mammen }
651ccf9ce32SBrock Mammen
GetDefaultColumn(DWORD,ULONG * pSort,ULONG * pDisplay)652ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetDefaultColumn(DWORD, ULONG *pSort, ULONG *pDisplay)
653ccf9ce32SBrock Mammen {
654ccf9ce32SBrock Mammen if (pSort)
655ccf9ce32SBrock Mammen *pSort = 0;
656ccf9ce32SBrock Mammen if (pDisplay)
657ccf9ce32SBrock Mammen *pDisplay = 0;
658ccf9ce32SBrock Mammen return S_OK;
659ccf9ce32SBrock Mammen }
660ccf9ce32SBrock Mammen
GetDefaultColumnState(UINT iColumn,DWORD * pcsFlags)661ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
662ccf9ce32SBrock Mammen {
663c0799cd2SBrock Mammen if (!pcsFlags)
664ccf9ce32SBrock Mammen return E_INVALIDARG;
665c0799cd2SBrock Mammen if (iColumn >= _countof(g_ColumnDefs))
666c0799cd2SBrock Mammen return m_pisfInner->GetDefaultColumnState(iColumn - _countof(g_ColumnDefs) + 1, pcsFlags);
667ccf9ce32SBrock Mammen *pcsFlags = g_ColumnDefs[iColumn].dwDefaultState;
668ccf9ce32SBrock Mammen return S_OK;
669ccf9ce32SBrock Mammen }
670ccf9ce32SBrock Mammen
GetDetailsEx(PCUITEMID_CHILD pidl,const SHCOLUMNID * pscid,VARIANT * pv)671ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
672ccf9ce32SBrock Mammen {
673c0799cd2SBrock Mammen return m_pisfInner->GetDetailsEx(pidl, pscid, pv);
674ccf9ce32SBrock Mammen }
675ccf9ce32SBrock Mammen
GetDetailsOf(PCUITEMID_CHILD pidl,UINT iColumn,SHELLDETAILS * pDetails)676ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *pDetails)
677ccf9ce32SBrock Mammen {
678ccf9ce32SBrock Mammen if (iColumn >= _countof(g_ColumnDefs))
679666bf346SBrock Mammen return m_pisfInner->GetDetailsOf(_ILGetFSPidl(pidl), iColumn - _countof(g_ColumnDefs) + 1, pDetails);
680ccf9ce32SBrock Mammen
681ccf9ce32SBrock Mammen pDetails->cxChar = g_ColumnDefs[iColumn].cxChar;
682ccf9ce32SBrock Mammen pDetails->fmt = g_ColumnDefs[iColumn].fmt;
683ccf9ce32SBrock Mammen
684ccf9ce32SBrock Mammen if (!pidl)
6856c6fd6d9SBrock Mammen return SHSetStrRet(&pDetails->str, _AtlBaseModule.GetResourceInstance(), g_ColumnDefs[iColumn].iResource);
686ccf9ce32SBrock Mammen
6872f6f24d0SAtharva Kulkarni if (iColumn == COL_LOCATION_INDEX)
688666bf346SBrock Mammen {
689a3ee648dSBrock Mammen return SHSetStrRet(&pDetails->str, _ILGetPath(pidl));
690666bf346SBrock Mammen }
691666bf346SBrock Mammen
6922f6f24d0SAtharva Kulkarni if (iColumn == COL_RELEVANCE_INDEX)
6932f6f24d0SAtharva Kulkarni {
6942f6f24d0SAtharva Kulkarni // TODO: Fill once the relevance is calculated
6952f6f24d0SAtharva Kulkarni return SHSetStrRet(&pDetails->str, "");
6962f6f24d0SAtharva Kulkarni }
6972f6f24d0SAtharva Kulkarni
698ccf9ce32SBrock Mammen return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str);
699ccf9ce32SBrock Mammen }
700ccf9ce32SBrock Mammen
MapColumnToSCID(UINT iColumn,SHCOLUMNID * pscid)701ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid)
702ccf9ce32SBrock Mammen {
703ccf9ce32SBrock Mammen UNIMPLEMENTED;
704ccf9ce32SBrock Mammen return E_NOTIMPL;
705ccf9ce32SBrock Mammen }
706ccf9ce32SBrock Mammen
707ccf9ce32SBrock Mammen // *** IShellFolder methods ***
ParseDisplayName(HWND hwndOwner,LPBC pbc,LPOLESTR lpszDisplayName,ULONG * pchEaten,PIDLIST_RELATIVE * ppidl,ULONG * pdwAttributes)708ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten,
709ccf9ce32SBrock Mammen PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
710ccf9ce32SBrock Mammen {
711ccf9ce32SBrock Mammen UNIMPLEMENTED;
712ccf9ce32SBrock Mammen return E_NOTIMPL;
713ccf9ce32SBrock Mammen }
714ccf9ce32SBrock Mammen
EnumObjects(HWND hwndOwner,DWORD dwFlags,LPENUMIDLIST * ppEnumIDList)715ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
716ccf9ce32SBrock Mammen {
717ccf9ce32SBrock Mammen *ppEnumIDList = NULL;
718ccf9ce32SBrock Mammen return S_FALSE;
719ccf9ce32SBrock Mammen }
720ccf9ce32SBrock Mammen
BindToObject(PCUIDLIST_RELATIVE pidl,LPBC pbcReserved,REFIID riid,LPVOID * ppvOut)721ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
722ccf9ce32SBrock Mammen {
723ccf9ce32SBrock Mammen UNIMPLEMENTED;
724ccf9ce32SBrock Mammen return E_NOTIMPL;
725ccf9ce32SBrock Mammen }
726ccf9ce32SBrock Mammen
BindToStorage(PCUIDLIST_RELATIVE pidl,LPBC pbcReserved,REFIID riid,LPVOID * ppvOut)727ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
728ccf9ce32SBrock Mammen {
729ccf9ce32SBrock Mammen UNIMPLEMENTED;
730ccf9ce32SBrock Mammen return E_NOTIMPL;
731ccf9ce32SBrock Mammen }
732ccf9ce32SBrock Mammen
CompareIDs(LPARAM lParam,PCUIDLIST_RELATIVE pidl1,PCUIDLIST_RELATIVE pidl2)733ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
734ccf9ce32SBrock Mammen {
735f0d6d989SBrock Mammen WORD wColumn = LOWORD(lParam);
736f0d6d989SBrock Mammen switch (wColumn)
737f0d6d989SBrock Mammen {
7382f6f24d0SAtharva Kulkarni case COL_NAME_INDEX: // Name
739f0d6d989SBrock Mammen break;
7402f6f24d0SAtharva Kulkarni case COL_LOCATION_INDEX: // Path
741f0d6d989SBrock Mammen return MAKE_COMPARE_HRESULT(StrCmpW(_ILGetPath(pidl1), _ILGetPath(pidl2)));
7422f6f24d0SAtharva Kulkarni case COL_RELEVANCE_INDEX: // Relevance
743f0d6d989SBrock Mammen return E_NOTIMPL;
744f0d6d989SBrock Mammen default: // Default columns
745f0d6d989SBrock Mammen wColumn -= _countof(g_ColumnDefs) - 1;
746f0d6d989SBrock Mammen break;
747f0d6d989SBrock Mammen }
748f0d6d989SBrock Mammen return m_pisfInner->CompareIDs(HIWORD(lParam) | wColumn, _ILGetFSPidl(pidl1), _ILGetFSPidl(pidl2));
749ccf9ce32SBrock Mammen }
750ccf9ce32SBrock Mammen
CreateViewObject(HWND hwndOwner,REFIID riid,LPVOID * ppvOut)751ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
752ccf9ce32SBrock Mammen {
753ccf9ce32SBrock Mammen if (riid == IID_IShellView)
754ccf9ce32SBrock Mammen {
755ccf9ce32SBrock Mammen SFV_CREATE sfvparams = {};
756ccf9ce32SBrock Mammen sfvparams.cbSize = sizeof(SFV_CREATE);
757ccf9ce32SBrock Mammen sfvparams.pshf = this;
7589c290040SBrock Mammen sfvparams.psfvcb = this;
759666bf346SBrock Mammen HRESULT hr = SHCreateShellFolderView(&sfvparams, (IShellView **) ppvOut);
760666bf346SBrock Mammen if (FAILED_UNEXPECTEDLY(hr))
761666bf346SBrock Mammen {
762666bf346SBrock Mammen return hr;
763666bf346SBrock Mammen }
764666bf346SBrock Mammen
765666bf346SBrock Mammen return ((IShellView * ) * ppvOut)->QueryInterface(IID_PPV_ARG(IShellFolderView, &m_shellFolderView));
766ccf9ce32SBrock Mammen }
767ccf9ce32SBrock Mammen return E_NOINTERFACE;
768ccf9ce32SBrock Mammen }
769ccf9ce32SBrock Mammen
GetAttributesOf(UINT cidl,PCUITEMID_CHILD_ARRAY apidl,DWORD * rgfInOut)770ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
771ccf9ce32SBrock Mammen {
772666bf346SBrock Mammen CComHeapPtr<PCITEMID_CHILD> aFSPidl;
773666bf346SBrock Mammen aFSPidl.Allocate(cidl);
774666bf346SBrock Mammen for (UINT i = 0; i < cidl; i++)
775666bf346SBrock Mammen {
776666bf346SBrock Mammen aFSPidl[i] = _ILGetFSPidl(apidl[i]);
777666bf346SBrock Mammen }
778666bf346SBrock Mammen
779666bf346SBrock Mammen return m_pisfInner->GetAttributesOf(cidl, aFSPidl, rgfInOut);
780ccf9ce32SBrock Mammen }
781ccf9ce32SBrock Mammen
782312b628fSBrock Mammen class CFindFolderContextMenu :
783312b628fSBrock Mammen public IContextMenu,
784312b628fSBrock Mammen public CComObjectRootEx<CComMultiThreadModelNoCS>
785ccf9ce32SBrock Mammen {
786312b628fSBrock Mammen CComPtr<IContextMenu> m_pInner;
787312b628fSBrock Mammen CComPtr<IShellFolderView> m_shellFolderView;
788312b628fSBrock Mammen UINT m_firstCmdId;
789312b628fSBrock Mammen static const UINT ADDITIONAL_MENU_ITEMS = 2;
790312b628fSBrock Mammen
791312b628fSBrock Mammen //// *** IContextMenu methods ***
QueryContextMenu(HMENU hMenu,UINT indexMenu,UINT idCmdFirst,UINT idCmdLast,UINT uFlags)792312b628fSBrock Mammen STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
793312b628fSBrock Mammen {
794312b628fSBrock Mammen m_firstCmdId = indexMenu;
795312b628fSBrock Mammen _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst++, MFT_STRING, MAKEINTRESOURCEW(IDS_SEARCH_OPEN_FOLDER), MFS_ENABLED);
796312b628fSBrock Mammen _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst++, MFT_SEPARATOR, NULL, 0);
797312b628fSBrock Mammen return m_pInner->QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
798312b628fSBrock Mammen }
799312b628fSBrock Mammen
InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)800312b628fSBrock Mammen STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
801312b628fSBrock Mammen {
802312b628fSBrock Mammen if (!IS_INTRESOURCE(lpcmi->lpVerb))
803312b628fSBrock Mammen {
804312b628fSBrock Mammen return m_pInner->InvokeCommand(lpcmi);
805312b628fSBrock Mammen }
806312b628fSBrock Mammen
807312b628fSBrock Mammen if (LOWORD(lpcmi->lpVerb) < m_firstCmdId + ADDITIONAL_MENU_ITEMS)
808312b628fSBrock Mammen {
809312b628fSBrock Mammen PCUITEMID_CHILD *apidl;
810312b628fSBrock Mammen UINT cidl;
811312b628fSBrock Mammen HRESULT hResult = m_shellFolderView->GetSelectedObjects(&apidl, &cidl);
812312b628fSBrock Mammen if (FAILED_UNEXPECTEDLY(hResult))
813312b628fSBrock Mammen return hResult;
814312b628fSBrock Mammen
815312b628fSBrock Mammen for (UINT i = 0; i < cidl; i++)
8162fdaa386SBrock Mammen {
817a3ee648dSBrock Mammen CComHeapPtr<ITEMIDLIST> folderPidl(ILCreateFromPathW(_ILGetPath(apidl[i])));
818312b628fSBrock Mammen if (!folderPidl)
8192fdaa386SBrock Mammen return E_OUTOFMEMORY;
8205be53f55SWhindmar Saksit LPCITEMIDLIST child = _ILGetFSPidl(apidl[i]);
8215be53f55SWhindmar Saksit SHOpenFolderAndSelectItems(folderPidl, 1, &child, 0);
822312b628fSBrock Mammen }
8235be53f55SWhindmar Saksit LocalFree(apidl); // Yes, LocalFree
824312b628fSBrock Mammen return S_OK;
8252fdaa386SBrock Mammen }
8262fdaa386SBrock Mammen
827312b628fSBrock Mammen CMINVOKECOMMANDINFOEX actualCmdInfo;
828312b628fSBrock Mammen memcpy(&actualCmdInfo, lpcmi, lpcmi->cbSize);
829312b628fSBrock Mammen actualCmdInfo.lpVerb -= ADDITIONAL_MENU_ITEMS;
830312b628fSBrock Mammen return m_pInner->InvokeCommand((CMINVOKECOMMANDINFO *)&actualCmdInfo);
831312b628fSBrock Mammen }
832312b628fSBrock Mammen
GetCommandString(UINT_PTR idCommand,UINT uFlags,UINT * lpReserved,LPSTR lpszName,UINT uMaxNameLen)833312b628fSBrock Mammen STDMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
834312b628fSBrock Mammen {
835312b628fSBrock Mammen return m_pInner->GetCommandString(idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
836312b628fSBrock Mammen }
837312b628fSBrock Mammen
838312b628fSBrock Mammen public:
Create(IShellFolderView * pShellFolderView,IContextMenu * pInnerContextMenu,IContextMenu ** pContextMenu)839312b628fSBrock Mammen static HRESULT Create(IShellFolderView *pShellFolderView, IContextMenu *pInnerContextMenu, IContextMenu **pContextMenu)
840312b628fSBrock Mammen {
841312b628fSBrock Mammen CComObject<CFindFolderContextMenu> *pObj;
842312b628fSBrock Mammen HRESULT hResult = CComObject<CFindFolderContextMenu>::CreateInstance(&pObj);
843312b628fSBrock Mammen if (FAILED_UNEXPECTEDLY(hResult))
844312b628fSBrock Mammen return hResult;
845312b628fSBrock Mammen pObj->m_shellFolderView = pShellFolderView;
846312b628fSBrock Mammen pObj->m_pInner = pInnerContextMenu;
847312b628fSBrock Mammen return pObj->QueryInterface(IID_PPV_ARG(IContextMenu, pContextMenu));
848312b628fSBrock Mammen }
849312b628fSBrock Mammen
850312b628fSBrock Mammen BEGIN_COM_MAP(CFindFolderContextMenu)
851312b628fSBrock Mammen COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
852312b628fSBrock Mammen END_COM_MAP()
853312b628fSBrock Mammen };
854312b628fSBrock Mammen
GetUIObjectOf(HWND hwndOwner,UINT cidl,PCUITEMID_CHILD_ARRAY apidl,REFIID riid,UINT * prgfInOut,LPVOID * ppvOut)855312b628fSBrock Mammen STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid,
856312b628fSBrock Mammen UINT *prgfInOut, LPVOID *ppvOut)
857312b628fSBrock Mammen {
858666bf346SBrock Mammen if (cidl <= 0)
859666bf346SBrock Mammen {
860c0799cd2SBrock Mammen return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
861ccf9ce32SBrock Mammen }
862ccf9ce32SBrock Mammen
863312b628fSBrock Mammen CComHeapPtr<PCITEMID_CHILD> aFSPidl;
864312b628fSBrock Mammen aFSPidl.Allocate(cidl);
865666bf346SBrock Mammen for (UINT i = 0; i < cidl; i++)
866666bf346SBrock Mammen {
867666bf346SBrock Mammen aFSPidl[i] = _ILGetFSPidl(apidl[i]);
868666bf346SBrock Mammen }
869666bf346SBrock Mammen
8702fdaa386SBrock Mammen if (riid == IID_IContextMenu)
8712fdaa386SBrock Mammen {
872a3ee648dSBrock Mammen CComHeapPtr<ITEMIDLIST> folderPidl(ILCreateFromPathW(_ILGetPath(apidl[0])));
873312b628fSBrock Mammen if (!folderPidl)
874312b628fSBrock Mammen return E_OUTOFMEMORY;
875312b628fSBrock Mammen CComPtr<IShellFolder> pDesktopFolder;
876312b628fSBrock Mammen HRESULT hResult = SHGetDesktopFolder(&pDesktopFolder);
877312b628fSBrock Mammen if (FAILED_UNEXPECTEDLY(hResult))
878312b628fSBrock Mammen return hResult;
879312b628fSBrock Mammen CComPtr<IShellFolder> pShellFolder;
880312b628fSBrock Mammen hResult = pDesktopFolder->BindToObject(folderPidl, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
881312b628fSBrock Mammen if (FAILED_UNEXPECTEDLY(hResult))
882312b628fSBrock Mammen return hResult;
883312b628fSBrock Mammen CComPtr<IContextMenu> pContextMenu;
884312b628fSBrock Mammen hResult = pShellFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, (LPVOID *)&pContextMenu);
885312b628fSBrock Mammen if (FAILED_UNEXPECTEDLY(hResult))
886312b628fSBrock Mammen return hResult;
887312b628fSBrock Mammen return CFindFolderContextMenu::Create(m_shellFolderView, pContextMenu, (IContextMenu **)ppvOut);
8882fdaa386SBrock Mammen }
8892fdaa386SBrock Mammen
890312b628fSBrock Mammen return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut);
891666bf346SBrock Mammen }
892666bf346SBrock Mammen
GetDisplayNameOf(PCUITEMID_CHILD pidl,DWORD dwFlags,LPSTRRET pName)893ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName)
894ccf9ce32SBrock Mammen {
895666bf346SBrock Mammen return m_pisfInner->GetDisplayNameOf(_ILGetFSPidl(pidl), dwFlags, pName);
896ccf9ce32SBrock Mammen }
897ccf9ce32SBrock Mammen
SetNameOf(HWND hwndOwner,PCUITEMID_CHILD pidl,LPCOLESTR lpName,DWORD dwFlags,PITEMID_CHILD * pPidlOut)898ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags,
899ccf9ce32SBrock Mammen PITEMID_CHILD *pPidlOut)
900ccf9ce32SBrock Mammen {
901ccf9ce32SBrock Mammen UNIMPLEMENTED;
902ccf9ce32SBrock Mammen return E_NOTIMPL;
903ccf9ce32SBrock Mammen }
9049c290040SBrock Mammen
9059c290040SBrock Mammen //// *** IShellFolderViewCB method ***
MessageSFVCB(UINT uMsg,WPARAM wParam,LPARAM lParam)9069c290040SBrock Mammen STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
9079c290040SBrock Mammen {
9089c290040SBrock Mammen switch (uMsg)
9099c290040SBrock Mammen {
9109c290040SBrock Mammen case SFVM_DEFVIEWMODE:
9119c290040SBrock Mammen {
9129c290040SBrock Mammen FOLDERVIEWMODE *pViewMode = (FOLDERVIEWMODE *) lParam;
9139c290040SBrock Mammen *pViewMode = FVM_DETAILS;
9149c290040SBrock Mammen return S_OK;
9159c290040SBrock Mammen }
91606fd04d7SBrock Mammen case SFVM_WINDOWCREATED:
91706fd04d7SBrock Mammen {
91807d37180SBrock Mammen // Subclass window to receive window messages
91906fd04d7SBrock Mammen SubclassWindow((HWND) wParam);
92004fcbe32SBrock Mammen
92107d37180SBrock Mammen // Get shell browser for updating status bar text
92204fcbe32SBrock Mammen CComPtr<IServiceProvider> pServiceProvider;
92304fcbe32SBrock Mammen HRESULT hr = m_shellFolderView->QueryInterface(IID_PPV_ARG(IServiceProvider, &pServiceProvider));
92404fcbe32SBrock Mammen if (FAILED_UNEXPECTEDLY(hr))
92504fcbe32SBrock Mammen return hr;
92607d37180SBrock Mammen hr = pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser));
92707d37180SBrock Mammen if (FAILED_UNEXPECTEDLY(hr))
92807d37180SBrock Mammen return hr;
92907d37180SBrock Mammen
93007d37180SBrock Mammen // Open search bar
93107d37180SBrock Mammen CComPtr<IWebBrowser2> pWebBrowser2;
93207d37180SBrock Mammen hr = m_shellBrowser->QueryInterface(IID_PPV_ARG(IWebBrowser2, &pWebBrowser2));
93307d37180SBrock Mammen if (FAILED_UNEXPECTEDLY(hr))
93407d37180SBrock Mammen return hr;
93507d37180SBrock Mammen WCHAR pwszGuid[MAX_PATH];
93607d37180SBrock Mammen StringFromGUID2(CLSID_FileSearchBand, pwszGuid, _countof(pwszGuid));
93707d37180SBrock Mammen CComVariant searchBar(pwszGuid);
93807d37180SBrock Mammen return pWebBrowser2->ShowBrowserBar(&searchBar, NULL, NULL);
93906fd04d7SBrock Mammen }
940*a17b6e93SWhindmar Saksit case SFVM_GETCOMMANDDIR:
941*a17b6e93SWhindmar Saksit {
942*a17b6e93SWhindmar Saksit HRESULT hr = E_FAIL;
943*a17b6e93SWhindmar Saksit if (m_shellFolderView)
944*a17b6e93SWhindmar Saksit {
945*a17b6e93SWhindmar Saksit PCUITEMID_CHILD *apidl;
946*a17b6e93SWhindmar Saksit UINT cidl = 0;
947*a17b6e93SWhindmar Saksit if (SUCCEEDED(hr = m_shellFolderView->GetSelectedObjects(&apidl, &cidl)))
948*a17b6e93SWhindmar Saksit {
949*a17b6e93SWhindmar Saksit if (cidl)
950*a17b6e93SWhindmar Saksit hr = StringCchCopyW((PWSTR)lParam, wParam, _ILGetPath(apidl[0]));
951*a17b6e93SWhindmar Saksit LocalFree(apidl);
952*a17b6e93SWhindmar Saksit }
953*a17b6e93SWhindmar Saksit }
954*a17b6e93SWhindmar Saksit return hr;
955*a17b6e93SWhindmar Saksit }
9569c290040SBrock Mammen }
9579c290040SBrock Mammen return E_NOTIMPL;
9589c290040SBrock Mammen }
9599c290040SBrock Mammen
960ccf9ce32SBrock Mammen //// *** IPersistFolder2 methods ***
GetCurFolder(PIDLIST_ABSOLUTE * pidl)961b90c24d6SThomas Faber STDMETHODIMP CFindFolder::GetCurFolder(PIDLIST_ABSOLUTE *pidl)
962ccf9ce32SBrock Mammen {
963ccf9ce32SBrock Mammen *pidl = ILClone(m_pidl);
964ccf9ce32SBrock Mammen return S_OK;
965ccf9ce32SBrock Mammen }
966ccf9ce32SBrock Mammen
967ccf9ce32SBrock Mammen // *** IPersistFolder methods ***
Initialize(PCIDLIST_ABSOLUTE pidl)968c2b476bdSThomas Faber STDMETHODIMP CFindFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
969ccf9ce32SBrock Mammen {
970ccf9ce32SBrock Mammen m_pidl = ILClone(pidl);
971ccf9ce32SBrock Mammen if (!m_pidl)
972ccf9ce32SBrock Mammen return E_OUTOFMEMORY;
973ccf9ce32SBrock Mammen
974c0799cd2SBrock Mammen return SHELL32_CoCreateInitSF(m_pidl,
975c0799cd2SBrock Mammen NULL,
976c0799cd2SBrock Mammen NULL,
977c0799cd2SBrock Mammen &CLSID_ShellFSFolder,
978c0799cd2SBrock Mammen IID_PPV_ARG(IShellFolder2, &m_pisfInner));
979ccf9ce32SBrock Mammen }
980ccf9ce32SBrock Mammen
981ccf9ce32SBrock Mammen // *** IPersist methods ***
GetClassID(CLSID * pClassId)982ccf9ce32SBrock Mammen STDMETHODIMP CFindFolder::GetClassID(CLSID *pClassId)
983ccf9ce32SBrock Mammen {
984ccf9ce32SBrock Mammen if (pClassId == NULL)
985ccf9ce32SBrock Mammen return E_INVALIDARG;
9868aa063b4SBrock Mammen *pClassId = CLSID_FindFolder;
987ccf9ce32SBrock Mammen return S_OK;
988ccf9ce32SBrock Mammen }
989