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