@@ -2387,172 +2387,97 @@ STDMETHODIMP CGDriveShlExt::ParseDisplayName(HWND hwnd, __in IBindCtx *pbc, __in
23872387 try
23882388 {
23892389 Log::WriteOutput (LogType::Warning, L" IShellFolder::ParseDisplayName name=%s" , pszDisplayName);
2390+ HRESULT hr = S_OK ;
2391+
2392+ CHECK_ARG (pszDisplayName != nullptr );
2393+ CHECK_ARG (ppidl != nullptr );
2394+
23902395 SetDialogType (hwnd);
23912396
23922397 // pdwAttrbiute is a set of SFGAOF flags, it's optional to filter by these
23932398
2394- HRESULT hr = S_OK ;
23952399 std::wstring nameOfChild; // To be determined
23962400 std::wstring pathFollowingChild (pszDisplayName);
23972401 CIdList ppidlOfChild;
23982402
23992403 BIND_OPTS options;
2400- hr = _GetContextOptions (pbc, options);
2404+ CHECK_HR ( _GetContextOptions (pbc, options) );
24012405
2402- if (SUCCEEDED (hr))
2406+ if (SUCCEEDED (
2407+ _NextNameSegment (pathFollowingChild, nameOfChild, &ppidlOfChild, pdwAttributes)))
24032408 {
2404- hr = _NextNameSegment (pathFollowingChild, nameOfChild, &ppidlOfChild, pdwAttributes);
2405-
2406- if (SUCCEEDED (hr))
2409+ if (pathFollowingChild.length () == 0 )
24072410 {
2408- if (pathFollowingChild.length () == 0 )
2409- {
2410- if ((options.grfMode & STGM_CREATE ) > 0 )
2411- {
2412- // We found a matching entry, but they want to create a new item with the same name, this we will not allow, so fail it out.
2413- hr = HRESULT_FROM_WIN32 (ERROR_FILE_EXISTS );
2414- }
2415- else if (options.grfFlags & BIND_JUSTTESTEXISTENCE )
2416- {
2417- hr = HRESULT_FROM_WIN32 (ERROR_FILE_EXISTS );
2418- }
2419- else
2420- {
2421- CIdList outPidl = *ppidl;
2422- hr = CIdList::Clone (ppidlOfChild, outPidl);
2423- *ppidl = outPidl.Release ();
2424- }
2425- }
2426- else
2427- {
2428- CComPtr<IShellFolder> spsf;
2429-
2430- hr = BindToObject (ppidlOfChild, pbc, IID_PPV_ARGS (&spsf));
2431-
2432- if (SUCCEEDED (hr))
2433- {
2434- CIdList spidlNext;
2435- {
2436- LPITEMIDLIST tmpNext;
2437- // This const cast is dangerous, and relies on knowing that ParseDisplayName will not attempt to overwrite the parameter
2438- // Since we know we're calling this on only our own objects, we can be sure.
2439- // DO NOT EDIT pszDisplayName in this function
2440- hr = spsf->ParseDisplayName (hwnd, pbc, const_cast <WCHAR *>(pathFollowingChild.c_str ()), NULL , &tmpNext, pdwAttributes);
2441- spidlNext.Reset (tmpNext);
2442- }
2443-
2444- if (SUCCEEDED (hr))
2445- {
2446- CIdList outPidl = *ppidl;
2447- hr = CIdList::Combine (ppidlOfChild, spidlNext, outPidl);
2448- *ppidl = outPidl.Release ();
2449- }
2450- }
2451- }
2411+ CHECK_TRUE ((options.grfMode & STGM_CREATE ) == 0 ,
2412+ // We found a matching entry, but they want to create a new item
2413+ // with the same name, this we will not allow, so fail it out.
2414+ HRESULT_FROM_WIN32 (ERROR_FILE_EXISTS ));
2415+ CHECK_TRUE ((options.grfFlags & BIND_JUSTTESTEXISTENCE ) == 0 ,
2416+ HRESULT_FROM_WIN32 (ERROR_FILE_EXISTS ));
2417+
2418+ CIdList outPidl = *ppidl;
2419+ CHECK_HR (CIdList::Clone (ppidlOfChild, outPidl));
2420+ *ppidl = outPidl.Release ();
24522421 }
24532422 else
24542423 {
2455- if ((options.grfMode & STGM_CREATE ) > 0 )
2456- {
2457- if (pathFollowingChild.length () == 0 && nameOfChild.length () > 0 )
2458- {
2459- if (nameOfChild.find (L" Google Drive" ) == 0 )
2460- {
2461- hr = E_FAIL ;
2462- Log::Error (L" CGDriveShlExt::ParseDisplayName() service cannot create root file" );
2463- }
2464- else
2465- {
2466- FileInfo* child = NULL ;
2467-
2468- bool isFolder = pdwAttributes != NULL && ((*pdwAttributes) & FILE_ATTRIBUTE_DIRECTORY ) > 0 ;
2469-
2470- if (_fileManager.InsertFile (_id, nameOfChild, isFolder, &child))
2471- {
2472- hr = _CreateItemID (child, &ppidlOfChild);
2424+ CComPtr<IShellFolder> spsf;
24732425
2474- if (SUCCEEDED (hr))
2475- {
2476- {
2477- CIdList outPidl = *ppidl;
2478- hr = CIdList::Clone (ppidlOfChild, outPidl);
2479- *ppidl = outPidl.Release ();
2480- }
2481-
2482- if (!child->CreatePathTo ())
2483- {
2484- Log::Error (L" CGDriveShlExt::ParseDisplayName() failed to create directory for placeholder file" );
2485- }
2486-
2487- FileInfo::Release (&child);
2426+ CHECK_HR (BindToObject (ppidlOfChild, pbc, IID_PPV_ARGS (&spsf)));
24882427
2489- CIdList pidlPath;
2490-
2491- HRESULT hr = CIdList::Combine (_spidl, *ppidl, pidlPath);
2492-
2493- _didUpdate = true ;
2494-
2495- if (!SUCCEEDED (hr))
2496- {
2497- Log::WriteOutput (LogType::Error, L" CombineIDLists returned hr=%d" , hr);
2498- }
2499- else
2500- {
2501- if (isFolder)
2502- {
2503- SHChangeNotify (SHCNE_MKDIR , SHCNF_IDLIST | SHCNF_FLUSH , pidlPath, pidlPath);
2504- }
2505- else
2506- {
2507- SHChangeNotify (SHCNE_CREATE , SHCNF_IDLIST | SHCNF_FLUSH , pidlPath, pidlPath);
2508- }
2509- }
2510-
2511- SHChangeNotify (SHCNE_UPDATEDIR | SHCNE_UPDATEITEM , SHCNF_IDLIST | SHCNF_FLUSH , _spidl, NULL );
2512- }
2513- }
2514- else
2515- {
2516- hr = E_FAIL ;
2517- Log::Error (L" CGDriveShlExt::ParseDisplayName() service failed to create a new file" );
2518- }
2519- }
2520- }
2521- else
2522- {
2523- Log::Error (L" CGDriveShlExt::ParseDisplayName() something unexpected happened" );
2524- }
2525- }
2526- else
2428+ CIdList spidlNext;
25272429 {
2528- hr = HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND );
2430+ LPITEMIDLIST tmpNext;
2431+ // This const cast is dangerous, and relies on knowing that ParseDisplayName will not attempt to overwrite the parameter
2432+ // Since we know we're calling this on only our own objects, we can be sure.
2433+ // DO NOT EDIT pszDisplayName in this function
2434+ CHECK_HR (spsf->ParseDisplayName (hwnd, pbc, const_cast <WCHAR *>(pathFollowingChild.c_str ()), NULL , &tmpNext, pdwAttributes));
2435+ spidlNext.Reset (tmpNext);
25292436 }
2437+
2438+ CIdList outPidl = *ppidl;
2439+ CHECK_HR (CIdList::Combine (ppidlOfChild, spidlNext, outPidl));
2440+ *ppidl = outPidl.Release ();
25302441 }
25312442 }
2532-
2533- if (pchEaten != NULL )
2443+ else
25342444 {
2535- if (SUCCEEDED (hr))
2445+ CHECK_TRUE ((options.grfMode & STGM_CREATE ) != 0 ,
2446+ HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND ));
2447+ CHECK_TRUE (pathFollowingChild.length () == 0 && nameOfChild.length () > 0 ,
2448+ E_FAIL );
2449+ CHECK_TRUE (nameOfChild.find (L" Google Drive" ) != 0 ,
2450+ // Service cannot create root file
2451+ E_FAIL );
2452+
2453+ FileInfo* child = NULL ;
2454+ bool isFolder = pdwAttributes != NULL && ((*pdwAttributes) & FILE_ATTRIBUTE_DIRECTORY ) > 0 ;
2455+ CHECK_TRUE (_fileManager.InsertFile (_id, nameOfChild, isFolder, &child),
2456+ E_FAIL );
2457+ CHECK_HR (_CreateItemID (child, &ppidlOfChild));
2458+
25362459 {
2537- // We parse the entire string, or we fail.
2538- (*pchEaten) = (ULONG )_tcslen (pszDisplayName);
2460+ CIdList outPidl = *ppidl;
2461+ CHECK_HR (CIdList::Clone (ppidlOfChild, outPidl));
2462+ *ppidl = outPidl.Release ();
25392463 }
2540- }
25412464
2542- if (!SUCCEEDED (hr))
2543- {
2544- CDriveItem driveItem;
2465+ CHECK_TRUE (child->CreatePathTo (), E_FAIL );
2466+ FileInfo::Release (&child);
25452467
2546- HRESULT errorhr = _GetDataFromIDList (_spidl, false , false , driveItem);
2468+ CIdList pidlPath;
2469+ CHECK_HR (CIdList::Combine (_spidl, *ppidl, pidlPath));
2470+ _didUpdate = true ;
25472471
2548- if (SUCCEEDED (errorhr))
2549- {
2550- Log::WriteOutput (LogType::Error, L" ParseDisplayName failed trying to parse to %s from %s" , pszDisplayName, driveItem.ItemName ().c_str ());
2551- }
2552- else
2553- {
2554- Log::WriteOutput (LogType::Error, L" ParseDisplayName failed trying to parse %s" , pszDisplayName);
2555- }
2472+ LONG eventId = isFolder? SHCNE_MKDIR : SHCNE_CREATE ;
2473+ SHChangeNotify (eventId, SHCNF_IDLIST | SHCNF_FLUSH , pidlPath, pidlPath);
2474+ SHChangeNotify (SHCNE_UPDATEDIR | SHCNE_UPDATEITEM , SHCNF_IDLIST | SHCNF_FLUSH , _spidl, NULL );
2475+ }
2476+
2477+ if (pchEaten != NULL )
2478+ {
2479+ // We parse the entire string, or we fail.
2480+ (*pchEaten) = (ULONG )_tcslen (pszDisplayName);
25562481 }
25572482
25582483 return hr;
@@ -2570,6 +2495,7 @@ HRESULT CGDriveShlExt::_NextNameSegment(__inout std::wstring& ppszInOut, __out s
25702495 try
25712496 {
25722497 Log::WriteOutput (LogType::Debug, L" CGDriveShlExt::_NextNameSegment" );
2498+ HRESULT hr = S_OK ;
25732499
25742500 std::wstring seperator = L" \\ " ;
25752501
@@ -2588,40 +2514,31 @@ HRESULT CGDriveShlExt::_NextNameSegment(__inout std::wstring& ppszInOut, __out s
25882514
25892515 CDriveItem item;
25902516
2591- HRESULT hr = _GetDataFromIDList (_spidl, false , true , item);
2517+ CHECK_HR ( _GetDataFromIDList (_spidl, false , true , item) );
25922518
2593- if (SUCCEEDED (hr))
2519+ hr = E_FAIL ;
2520+ auto & itemFiles = *item.Files ();
2521+ for (auto it = itemFiles.begin (); it != itemFiles.end (); it++)
25942522 {
2595- hr = E_FAIL ;
2523+ FileInfo* child = *it ;
25962524
2597- for (std::vector<FileInfo*>::iterator it = item.Files ()->begin (); it != item.Files ()->end (); it++)
2525+ // This showed up with WantsFORPARSING was set, which is not normally set
2526+ // lets just keep this code in place till we find a reason not to
2527+ if (child->Id .compare (ppszSegment) == 0 && child->Title .compare (ppszInOut) == 0 )
25982528 {
2599- FileInfo* child = *it;
2600-
2601- // This showed up with WantsFORPARSING was set, which is not normally set
2602- // lets just keep this code in place till we find a reason not to
2603- if (child->Id .compare (ppszSegment) == 0 && child->Title .compare (ppszInOut) == 0 )
2604- {
2605- // changing ppszSegment here, so the next compare is different
2606- ppszSegment.assign (ppszInOut);
2607- ppszInOut.assign (L" " );
2608- }
2529+ // changing ppszSegment here, so the next compare is different
2530+ ppszSegment.assign (ppszInOut);
2531+ ppszInOut.assign (L" " );
2532+ }
26092533
2610- if (child->Title .compare (ppszSegment) == 0 ) // Should this be case insensitive? Windows doesn't allow it but Google does
2534+ if (child->Title .compare (ppszSegment) == 0 ) // Should this be case insensitive? Windows doesn't allow it but Google does
2535+ {
2536+ if (pdwAttributes != NULL )
26112537 {
2612- hr = _CreateItemID (child, ppidlOut);
2613-
2614- if (SUCCEEDED (hr) && pdwAttributes != NULL )
2615- {
2616- DWORD dwMask = 0 ;
2617-
2618- hr = _GetAttributesOf (child, &dwMask);
2619-
2620- if (SUCCEEDED (hr))
2621- {
2622- *pdwAttributes = *pdwAttributes & dwMask;
2623- }
2624- }
2538+ CHECK_HR (_CreateItemID (child, ppidlOut));
2539+ DWORD dwMask = 0 ;
2540+ CHECK_HR (_GetAttributesOf (child, &dwMask));
2541+ *pdwAttributes = *pdwAttributes & dwMask;
26252542 }
26262543 }
26272544 }
0 commit comments