Skip to content
This repository was archived by the owner on Nov 11, 2022. It is now read-only.

Commit 41a94a1

Browse files
committed
Merge pull request #19 from jpgaribotti/master
Error reporting improvements
2 parents 6ff622d + 6183eb8 commit 41a94a1

4 files changed

Lines changed: 96 additions & 173 deletions

File tree

DriveFusion/ErrorSignaling.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@ limitations under the License.
1515
*/
1616
#pragma once
1717

18+
#define LSTR_(value) L#value
19+
20+
#define LSTR(value) LSTR_(value)
21+
1822
#define CHECK_ARG(condition) \
1923
do \
2024
{ \
2125
if (!(condition)) \
2226
{ \
2327
hr = E_INVALIDARG; \
2428
Log::WriteOutput( \
25-
LogType::Error, L"\tArgument failed condition " L#condition); \
29+
LogType::Error, LSTR(__FILE__) L":" LSTR(__LINE__) \
30+
L" - Argument failed condition " L#condition); \
2631
return hr; \
2732
} \
2833
} while (false)
@@ -34,7 +39,8 @@ limitations under the License.
3439
if (!SUCCEEDED(hr)) \
3540
{ \
3641
Log::WriteOutput( \
37-
LogType::Error, L"\t" L#hresult L" failed, hr = %x", hr); \
42+
LogType::Error, LSTR(__FILE__) L":" LSTR(__LINE__) \
43+
L" - " L#hresult L" failed, hr = %x", hr); \
3844
return hr; \
3945
} \
4046
} while (false)
@@ -46,8 +52,8 @@ limitations under the License.
4652
{ \
4753
hr = hrFail; \
4854
Log::WriteOutput( \
49-
LogType::Error, \
50-
L"\t" L#condition L" failed, " L#hrFail L" = %x", hr); \
55+
LogType::Error, LSTR(__FILE__) L":" LSTR(__LINE__) \
56+
L" - " L#condition L" failed, " L#hrFail L" = %x", hr); \
5157
return hr; \
5258
} \
5359
} while (false)

DriveFusion/GDriveShlExt.cpp

Lines changed: 84 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

ProjectConfig.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Version 1.8.55.0
1+
Version 1.8.55.1
22
Title Google Drive Shell Extension
33
Description A shell extension to map your Google Drive.
44
Company Google Inc

0 commit comments

Comments
 (0)