1 #include "shelltest.h"
2 
3 // + Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20130503-00/?p=4463/
4 // In short: We want to create an IDLIST from an item that does not exist,
5 // so we have to provide WIN32_FIND_DATAW in a bind context.
6 // If we don't, the FS will be queried, and we do not get a valid IDLIST for a non-existing path.
7 
8 CComModule gModule;
9 
10 class CFileSysBindData :
11     public CComCoClass<CFileSysBindData>,
12     public CComObjectRootEx<CComMultiThreadModelNoCS>,
13     public IFileSystemBindData
14 {
15 public:
16     virtual HRESULT STDMETHODCALLTYPE SetFindData(const WIN32_FIND_DATAW *pfd)
17     {
18         m_Data = *pfd;
19         return S_OK;
20     }
21 
22     virtual HRESULT STDMETHODCALLTYPE GetFindData(WIN32_FIND_DATAW *pfd)
23     {
24         *pfd = m_Data;
25         return S_OK;
26     }
27 
28     DECLARE_NOT_AGGREGATABLE(CFileSysBindData)
29     DECLARE_PROTECT_FINAL_CONSTRUCT()
30     BEGIN_COM_MAP(CFileSysBindData)
31         COM_INTERFACE_ENTRY_IID(IID_IFileSystemBindData, IFileSystemBindData)
32     END_COM_MAP()
33 private:
34     WIN32_FIND_DATAW m_Data;
35 };
36 
37 static
38 HRESULT
39 AddFileSysBindCtx(_In_ IBindCtx *pbc)
40 {
41     CComPtr<IFileSystemBindData> spfsbc(new CComObject<CFileSysBindData>());
42     WIN32_FIND_DATAW wfd = { 0 };
43     wfd.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
44     spfsbc->SetFindData(&wfd);
45     HRESULT hr = pbc->RegisterObjectParam((LPOLESTR)STR_FILE_SYS_BIND_DATA, spfsbc);
46     ok(hr == S_OK, "hr = %lx\n", hr);
47     return hr;
48 }
49 
50 static
51 HRESULT
52 CreateBindCtxWithOpts(_In_ BIND_OPTS *pbo, _Outptr_ IBindCtx **ppbc)
53 {
54     CComPtr<IBindCtx> spbc;
55     HRESULT hr = CreateBindCtx(0, &spbc);
56     ok(hr == S_OK, "hr = %lx\n", hr);
57     if (SUCCEEDED(hr))
58     {
59         hr = spbc->SetBindOptions(pbo);
60         ok(hr == S_OK, "hr = %lx\n", hr);
61     }
62     *ppbc = SUCCEEDED(hr) ? spbc.Detach() : NULL;
63     return hr;
64 }
65 
66 static HRESULT
67 CreateFileSysBindCtx(_Outptr_ IBindCtx **ppbc)
68 {
69     CComPtr<IBindCtx> spbc;
70     BIND_OPTS bo = { sizeof(bo), 0, STGM_CREATE, 0 };
71     HRESULT hr = CreateBindCtxWithOpts(&bo, &spbc);
72     ok(hr == S_OK, "hr = %lx\n", hr);
73     if (SUCCEEDED(hr))
74     {
75         hr = AddFileSysBindCtx(spbc);
76         ok(hr == S_OK, "hr = %lx\n", hr);
77     }
78     *ppbc = SUCCEEDED(hr) ? spbc.Detach() : NULL;
79     return hr;
80 }
81 
82 VOID
83 PathToIDList(LPCWSTR pszPath, ITEMIDLIST** ppidl)
84 {
85     CComPtr<IBindCtx> spbc;
86     HRESULT hr = CreateFileSysBindCtx(&spbc);
87     ok(hr == S_OK, "hr = %lx\n", hr);
88     if (SUCCEEDED(hr))
89     {
90         hr = SHParseDisplayName(pszPath, spbc, ppidl, 0, NULL);
91         ok(hr == S_OK, "hr = %lx\n", hr);
92     }
93 }
94 
95 // - Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20130503-00/?p=4463/
96