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