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