Skip to content

Commit

Permalink
Fixed failing unit test: TestShellExtension.testDefaultDllCanUnloadNo…
Browse files Browse the repository at this point in the history
…w() #115

Removed conflicting code in CContextMenu.cpp which was overriding ATL code.
Fixed custom DllMain() code which was using HRESULT instead of BOOL for return type.
Removed debugging code: SA_ENABLE_ATTACH_HOOK_DEBUGGING.
  • Loading branch information
end2endzone committed Jan 4, 2024
1 parent 22d3d87 commit fc092bf
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 85 deletions.
79 changes: 1 addition & 78 deletions src/shellextension/CContextMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ HRESULT STDMETHODCALLTYPE CContextMenu::Initialize(LPCITEMIDLIST pIDFolder, LPDA
std::wstring path(length, '\0');
if (path.size() != length)
continue;
size_t num_characters = length + 1;
size_t num_characters = size_t(length) + 1;

// Copy the element into the temporary buffer
DragQueryFileW(hDropInfo, i, (wchar_t*)path.data(), (UINT)num_characters);
Expand All @@ -626,80 +626,3 @@ HRESULT STDMETHODCALLTYPE CContextMenu::Initialize(LPCITEMIDLIST pIDFolder, LPDA

return S_OK;
}

HRESULT STDMETHODCALLTYPE CContextMenu::QueryInterface(REFIID riid, LPVOID FAR* ppv)
{
std::string riid_str = GuidToInterfaceName(riid);
SA_LOG(INFO) << __FUNCTION__ << "(), riid=" << riid_str << ", this=" << ToHexString(this);

HRESULT hr = E_NOINTERFACE;

#if SA_QUERYINTERFACE_IMPL == 0
//https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/implementing-iunknown-in-c-plus-plus

// Always set out parameter to NULL, validating it first.
if (!ppv)
return E_INVALIDARG;
*ppv = NULL;

////Filter out unimplemented known interfaces so they do not show as WARNINGS
//if (IsEqualGUID(riid, IID_IObjectWithSite) || //{FC4801A3-2BA9-11CF-A229-00AA003D7352}
// IsEqualGUID(riid, IID_IInternetSecurityManager) || //{79EAC9EE-BAF9-11CE-8C82-00AA004BA90B}
// IsEqualGUID(riid, IID_IContextMenu2) || //{000214f4-0000-0000-c000-000000000046}
// IsEqualGUID(riid, IID_IContextMenu3) || //{BCFCE0A0-EC17-11d0-8D10-00A0C90F2719}
// IsEqualGUID(riid, CLSID_UNDOCUMENTED_01)
// )
//{
// SA_LOG(INFO) << __FUNCTION__ << "(), interface not supported " << riid_str;
// return E_NOINTERFACE;
//}

//https://stackoverflow.com/questions/1742848/why-exactly-do-i-need-an-explicit-upcast-when-implementing-queryinterface-in-a
if (IsEqualGUID(riid, IID_IUnknown)) *ppv = (LPVOID)this;
if (IsEqualGUID(riid, IID_IShellExtInit)) *ppv = (LPSHELLEXTINIT)this;
if (IsEqualGUID(riid, IID_IContextMenu)) *ppv = (LPCONTEXTMENU)this;

if (*ppv)
{
AddRef();
hr = S_OK;
}
else
hr = E_NOINTERFACE;
#elif SA_QUERYINTERFACE_IMPL == 1
static const QITAB qit[] =
{
QITABENT(CContextMenu, IShellExtInit),
QITABENT(CContextMenu, IContextMenu),
{ 0, 0 },
};
hr = QISearch(this, qit, riid, ppv);
#endif

if (SUCCEEDED(hr))
SA_LOG(INFO) << __FUNCTION__ << "(), found interface " << riid_str << ", ppv=" << ToHexString(*ppv);
else
SA_LOG(INFO) << __FUNCTION__ << "(), unknown interface " << riid_str;
return hr;
}

ULONG STDMETHODCALLTYPE CContextMenu::AddRef()
{
//https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/implementing-iunknown-in-c-plus-plus

// Increment the object's internal counter.
return InterlockedIncrement(&m_refCount);
}

ULONG STDMETHODCALLTYPE CContextMenu::Release()
{
//https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/implementing-iunknown-in-c-plus-plus

// Decrement the object's internal counter.
LONG refCount = InterlockedDecrement(&m_refCount);
if (refCount == 0)
{
delete this;
}
return refCount;
}
18 changes: 13 additions & 5 deletions src/shellextension/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include "SaUtils.h"
#include "utils.h"

#include "rapidassist/errors.h"

//Declarations
shellanything::ILoggerService* logger_service = NULL;
shellanything::IRegistryService* registry_service = NULL;
Expand Down Expand Up @@ -136,11 +138,16 @@ STDAPI DllUnregisterServer(void)

extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
HRESULT hr = _AtlModule.DllMain(dwReason, lpReserved);
if (FAILED(hr))
BOOL result = _AtlModule.DllMain(dwReason, lpReserved);
if (result == FALSE)
{
SA_LOG(ERROR) << "Failed initializing module DLLMain()";
return hr;
SA_LOG(ERROR) << "Failed initializing module DLLMain().";

ra::errors::errorcode_t code = ra::errors::GetLastErrorCode();
std::string desc = ra::errors::GetErrorCodeDescription(code);

SA_LOG(ERROR) << "ERROR: 0x" << std::hex << code << std::dec << ", " << desc;
return result;
}

// Skip log initializations and default configuration installation if process that is loading this dll is regsvr32.exe.
Expand Down Expand Up @@ -201,10 +208,11 @@ extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpRe
}
}

return S_OK;
return result;
}

// DllInstall - Adds/Removes entries to the system registry per user per machine.
_Use_decl_annotations_
STDAPI DllInstall(BOOL bInstall, _In_opt_ LPCWSTR pszCmdLine)
{
ATTACH_HOOK_DEBUGGING;
Expand Down
2 changes: 1 addition & 1 deletion src/shellextension/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@
#include <atlcom.h>

// Debugging support
#define SA_ENABLE_ATTACH_HOOK_DEBUGGING
//#define SA_ENABLE_ATTACH_HOOK_DEBUGGING
//#define SA_ENABLE_SCOPE_DEBUGGING
4 changes: 3 additions & 1 deletion src/tests/TestShellExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ namespace shellanything

ShellExtensionLibraryHandler() :
mFailed(true),
mModule(NULL)
mModule(NULL),
pfnDllGetClassObject(NULL),
pfnDllCanUnloadNow(NULL)
{
std::string path = GetShellExtensionDllPath();

Expand Down

0 comments on commit fc092bf

Please sign in to comment.