Page MenuHome GnuPG

No OneTemporary

diff --git a/src/gpga/CMakeLists.txt b/src/gpga/CMakeLists.txt
index 3502ad1..075a854 100644
--- a/src/gpga/CMakeLists.txt
+++ b/src/gpga/CMakeLists.txt
@@ -1,29 +1,30 @@
# Copyright (C) 2018 Andre Heinecke <aheinecke@gnupg.com>
#
# This file is Free Software under the GNU GPL (v>=2)
# and comes with ABSOLUTELY NO WARRANTY!
# See LICENSE.txt for details.
set(EXECUTABLE_NAME "gpga")
set(EXECUTABLE_SRC
flange.cpp
../util/debug.cpp
../util/w32-util.cpp
gpga.def
gpgshellfolder.cpp
+ gpgpersistfolder.cpp
)
add_library (${EXECUTABLE_NAME}
${EXECUTABLE_SRC}
)
target_link_libraries(${EXECUTABLE_NAME}
PRIVATE Gpgmepp
)
set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS "-municode")
set_target_properties(${EXECUTABLE_NAME} PROPERTIES PREFIX "")
install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)
diff --git a/src/gpga/flange.cpp b/src/gpga/flange.cpp
index 15c5144..94b55b8 100644
--- a/src/gpga/flange.cpp
+++ b/src/gpga/flange.cpp
@@ -1,277 +1,283 @@
/* Copyright (C) 2018 by Andre Heinecke <aheinecke@gnupg.com>
*
* This file is Free Software under the GNU GPL (v>=2)
* and comes with ABSOLUTELY NO WARRANTY!
* See LICENSE.txt for details.
*/
#include "flange.h"
#include "debug.h"
#include "comhelp.h"
#include "w32-util.h"
#include "gpgshellfolder.h"
#include "shlobj.h"
/** @file Code to flange to the Windows explorer.
*
* This file contains the Windows and COM API requirements
* to properly work as an explorer extension.
*/
#ifndef INITGUID
/* Include every header that defines a GUID below this
macro. Otherwise the GUID's will only be declared and
not defined. */
#define INITGUID
#endif
#include <initguid.h>
#define MY_CLSID_STR "CCD955E4-5C16-4A33-AFDA-A8947A94946C"
DEFINE_GUID(MY_CLSID, 0xCCD955E4, 0x5C16, 0x4A33,
0xAF, 0xDA, 0xA8, 0x94, 0x7A, 0x94, 0x94, 0x6C);
#define MY_PROGID "GpgArchive"
static HINSTANCE s_hinst;
static FlangeFactory *s_factory;
static void init_logging()
{
static bool wasDone;
if (!wasDone) {
gpgrt_log_set_sink("c:\\tmp\\gpga.txt", nullptr, -1);
wasDone = true;
}
}
+CLSID getFlangeCLSID ()
+{
+ return MY_CLSID;
+}
+
/* Here we go */
STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
init_logging ();
+ log_debug ("\nGetClassObject");
if (!ppv) {
return E_POINTER;
}
*ppv = nullptr;
if (rclsid == MY_CLSID) {
return FlangeFactory::instance()->QueryInterface(riid, ppv);
}
log_debug ("Get class object for nonimp clsid'" GUID_FMT "'",
GUID_ARG(riid));
return CLASS_E_CLASSNOTAVAILABLE;
}
STDMETHODIMP FlangeFactory::LockServer (BOOL lock)
{
if (lock) {
AddRef();
} else {
Release();
}
return S_OK;
}
STDMETHODIMP FlangeFactory::CreateInstance (LPUNKNOWN,
REFIID riid,
LPVOID* ppvObj)
{
if (riid == IID_IShellFolder) {
auto folder = new GpgShellFolder();
return folder->QueryInterface (riid, ppvObj);
}
log_debug ("CreateInstance with unimplemented id '" GUID_FMT "'",
GUID_ARG(riid));
return E_NOINTERFACE;
}
STDMETHODIMP FlangeFactory::QueryInterface (REFIID riid, void **ppv)
{
if (!ppv) {
return E_POINTER;
}
*ppv = nullptr;
/* The static casts ensure that the virtual function table
layout of the returned object is correct. */
if (riid == IID_IUnknown) {
*ppv = static_cast<IUnknown *> (this);
} else if (riid == IID_IClassFactory) {
*ppv = static_cast<IClassFactory *> (this);
} else {
log_debug("QueryInterface with unknwon interface: '" GUID_FMT "'",
GUID_ARG(riid));
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef ();
return S_OK;
}
FlangeFactory *FlangeFactory::instance()
{
if (!s_factory) {
s_factory = new FlangeFactory();
}
return s_factory;
}
STDMETHODIMP_(ULONG) FlangeFactory::Release()
{
ULONG lCount = --m_lRef;
if (!lCount) {
delete this;
}
return lCount;
}
FlangeFactory::~FlangeFactory()
{
s_factory = nullptr;
}
STDAPI DllCanUnloadNow()
{
return s_factory == nullptr;
}
STDAPI DllUnregisterServer()
{
HKEY root_key;
if (W32::isElevated()) {
root_key = HKEY_LOCAL_MACHINE;
} else {
root_key = HKEY_CURRENT_USER;
}
log_debug("Un Registering shell extension.");
RegDeleteKeyA(root_key, "Software\\Classes\\.gpga");
RegDeleteKeyA(root_key, "Software\\Classes\\GPGArchive");
RegDeleteKeyA(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}");
}
STDAPI DllRegisterServer()
{
const char *root_key;
const auto gpg4windir = W32::getGpg4winDir();
init_logging ();
log_debug ("Debug");
if (gpg4windir.empty()) {
STRANGEPOINT;
return FALSE;
}
char module_path[MAX_PATH + 1];
if (!s_hinst || GetModuleFileNameA (s_hinst, module_path,
MAX_PATH) == MAX_PATH) {
STRANGEPOINT;
return FALSE;
}
if (W32::isElevated()) {
root_key = "HKEY_LOCAL_MACHINE";
} else {
root_key = "HKEY_CURRENT_USER";
}
log_debug("Registering shell extension.");
/* Tar file is: {2B3256E4-49AA-11D3-8229-0050AE509054} */
/* Register File extension */
if (!W32::writeRegStr(root_key, "Software\\Classes\\.gpga",
nullptr, MY_PROGID)) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\GPGArchive",
nullptr, "GnuPG Archive Extension")) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\GPGArchive",
"FriendlyTypeName", "GnuPG Archive")) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\GPGArchive\\ShellEx",
nullptr, "")) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\GPGArchive\\CLSID",
nullptr, "{" MY_CLSID_STR "}")) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\GPGArchive\\CLSID",
nullptr, "{" MY_CLSID_STR "}")) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}",
nullptr, "GnuPG Archive Extension")) {
STRANGEPOINT;
return FALSE;
}
std::string iconPath = gpg4windir + "\\share\\gpg4win\\file-ext.ico";
if (!W32::writeRegStr(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}",
"Default Icon", iconPath.c_str())) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}\\InprocServer32",
nullptr, module_path)) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}\\InprocServer32",
"ThreadingModel", "Apartment")) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}\\ProgID",
nullptr, MY_PROGID)) {
STRANGEPOINT;
return FALSE;
}
if (!W32::writeRegStr(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}\\Implemented Categories\\"
"{00021490-0000-0000-C000-000000000046}",
nullptr, "Browsable Shell Extension")) {
STRANGEPOINT;
return FALSE;
}
/* See: https://msdn.microsoft.com/en-us/library/windows/desktop/cc144093(v=vs.85).aspx */
if (!W32::writeRegDword(root_key, "Software\\Classes\\CLSID\\{" MY_CLSID_STR "}\\ShellFolder",
"Attributes", SFGAO_FOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE)) {
STRANGEPOINT;
return FALSE;
}
/* Notify the shell about the change. */
SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
}
STDAPI DllMain (HINSTANCE hinst, DWORD reason, LPVOID)
{
if (reason == DLL_PROCESS_ATTACH) {
s_hinst = hinst;
// Do init of GPGME
init_logging ();
} else if (reason == DLL_PROCESS_DETACH) {
log_debug ("Detached");
}
return TRUE;
}
diff --git a/src/gpga/flange.h b/src/gpga/flange.h
index 7801824..d291106 100644
--- a/src/gpga/flange.h
+++ b/src/gpga/flange.h
@@ -1,36 +1,38 @@
#ifndef FLANGE_H
#define FLANGE_H
/* Copyright (C) 2018 by Andre Heinecke <aheinecke@gnupg.com>
*
* This file is Free Software under the GNU GPL (v>=2)
* and comes with ABSOLUTELY NO WARRANTY!
* See LICENSE.txt for details.
*/
#include <windows.h>
class FlangeFactory: public IClassFactory
{
protected:
FlangeFactory(): m_lRef(0) {}
public:
virtual ~FlangeFactory();
STDMETHODIMP QueryInterface (REFIID riid, LPVOID* ppvObj);
STDMETHODIMP_(ULONG) AddRef() { ++m_lRef; return m_lRef; };
STDMETHODIMP_(ULONG) Release();
/* IClassFactory */
STDMETHODIMP CreateInstance (LPUNKNOWN unknown, REFIID riid,
LPVOID* ppvObj);
STDMETHODIMP LockServer (BOOL lock);
/* Custom */
static FlangeFactory *instance();
private:
ULONG m_lRef;
};
+CLSID getFlangeCLSID();
+
#endif // FLANGE_H
diff --git a/src/gpga/gpgpersistfolder.cpp b/src/gpga/gpgpersistfolder.cpp
new file mode 100644
index 0000000..452c0cb
--- /dev/null
+++ b/src/gpga/gpgpersistfolder.cpp
@@ -0,0 +1,111 @@
+/* Copyright (C) 2019 by Andre Heinecke <aheinecke@gnupg.com>
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+#include "gpgpersistfolder.h"
+#include "debug.h"
+
+#include "flange.h"
+
+STDMETHODIMP GpgPersistFolder::QueryInterface (REFIID riid, void **ppv)
+{
+ TRACEPOINT;
+ if (!ppv) {
+ return E_POINTER;
+ }
+
+ *ppv = nullptr;
+ log_debug("QueryInterface for: '" GUID_FMT "'",
+ GUID_ARG(riid));
+
+ /* The static casts ensure that the virtual function table
+ layout of the returned object is correct. */
+ if (riid == IID_IUnknown) {
+ TRACEPOINT;
+ *ppv = static_cast<IUnknown *> (this);
+ } else if (riid == IID_IPersistFolder) {
+ TRACEPOINT;
+ *ppv = static_cast<IPersistFolder*> (this);
+ } else if (riid == IID_IPersistFolder2) {
+ TRACEPOINT;
+ *ppv = static_cast<IPersistFolder2*> (this);
+ } else if (riid == IID_IPersistFolder3) {
+ TRACEPOINT;
+ *ppv = static_cast<IPersistFolder3*> (this);
+ } else if (riid == IID_IPersist) {
+ TRACEPOINT;
+ *ppv = static_cast<IPersist*> (this);
+ } else {
+ log_debug("QueryInterface with unknown interface: '" GUID_FMT "'",
+ GUID_ARG(riid));
+ return E_NOINTERFACE;
+ }
+
+ reinterpret_cast<IUnknown *>(*ppv)->AddRef ();
+
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE GpgPersistFolder::Release()
+{
+ TRACEPOINT;
+ ULONG lCount = --m_lRef;
+ if (!lCount) {
+ delete this;
+ }
+ return lCount;
+}
+
+GpgPersistFolder::GpgPersistFolder():
+ m_lRef(0),
+ m_pidl(nullptr)
+{
+
+}
+
+GpgPersistFolder::~GpgPersistFolder()
+{
+ TRACEPOINT;
+ if (m_pidl) {
+ CoTaskMemFree(m_pidl);
+ }
+}
+
+HRESULT STDMETHODCALLTYPE GpgPersistFolder::GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO *ppfti)
+{
+ TRACEPOINT;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE GpgPersistFolder::InitializeEx(IBindCtx *pbc,
+ PCIDLIST_ABSOLUTE pidlRoot,
+ const PERSIST_FOLDER_TARGET_INFO *ppfti)
+{
+ TRACEPOINT;
+ Initialize (pidlRoot);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE GpgPersistFolder::GetCurFolder(PIDLIST_ABSOLUTE *ppidl)
+{
+ TRACEPOINT;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE GpgPersistFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
+{
+ TRACEPOINT;
+ m_pidl = ILCloneFull(pidl);
+ return m_pidl ? S_OK : E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE GpgPersistFolder::GetClassID(CLSID *pClassID)
+{
+ TRACEPOINT;
+ *pClassID = getFlangeCLSID();
+
+ return S_OK;
+}
diff --git a/src/gpga/gpgpersistfolder.h b/src/gpga/gpgpersistfolder.h
new file mode 100644
index 0000000..8ae172e
--- /dev/null
+++ b/src/gpga/gpgpersistfolder.h
@@ -0,0 +1,43 @@
+#ifndef GPGA_GPGPERSISTFOLDER_H
+#define GPGA_GPGPERSISTFOLDER_H
+/* Copyright (C) 2018 by Andre Heinecke <aheinecke@gnupg.com>
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+#include <windows.h>
+#include <shlobj.h>
+
+class GpgPersistFolder: public IPersistFolder3
+{
+public:
+ GpgPersistFolder();
+
+ virtual ~GpgPersistFolder();
+
+ /* IUnknown */
+ STDMETHODIMP QueryInterface (REFIID riid, LPVOID* ppvObj);
+ STDMETHODIMP_(ULONG) AddRef() { ++m_lRef; return m_lRef; };
+ STDMETHODIMP_(ULONG) Release();
+
+ /* IPersist */
+ HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
+
+ /* IPersistFolder3 */
+ HRESULT STDMETHODCALLTYPE GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO *ppfti);
+ HRESULT STDMETHODCALLTYPE InitializeEx(IBindCtx *pbc, PCIDLIST_ABSOLUTE pidlRoot,
+ const PERSIST_FOLDER_TARGET_INFO *ppfti);
+ /* IPersistFolder2 */
+ HRESULT STDMETHODCALLTYPE GetCurFolder(PIDLIST_ABSOLUTE *ppidl);
+
+ /* IPersistFolder */
+ HRESULT STDMETHODCALLTYPE Initialize(PCIDLIST_ABSOLUTE pidl);
+
+ /* custom */
+ PIDLIST_ABSOLUTE pidl() {return m_pidl;}
+private:
+ ULONG m_lRef;
+ PIDLIST_ABSOLUTE m_pidl;
+};
+#endif // GPGA_GPGPERSISTFOLDER_H
diff --git a/src/gpga/gpgshellfolder.cpp b/src/gpga/gpgshellfolder.cpp
index 17caeb7..9a1daae 100644
--- a/src/gpga/gpgshellfolder.cpp
+++ b/src/gpga/gpgshellfolder.cpp
@@ -1,146 +1,209 @@
/* Copyright (C) 2018 by Andre Heinecke <aheinecke@gnupg.com>
*
* This file is Free Software under the GNU GPL (v>=2)
* and comes with ABSOLUTELY NO WARRANTY!
* See LICENSE.txt for details.
*/
#include "gpgshellfolder.h"
+#include "gpgpersistfolder.h"
#include "debug.h"
+GpgShellFolder::GpgShellFolder() :
+ m_lRef(0),
+ m_persistFolder(new GpgPersistFolder())
+{
+ m_persistFolder->AddRef();
+}
+
GpgShellFolder::~GpgShellFolder()
{
+ m_persistFolder->Release();
}
STDMETHODIMP GpgShellFolder::QueryInterface (REFIID riid, void **ppv)
{
- if (!ppv) {
- return E_POINTER;
- }
-
- *ppv = nullptr;
-
- /* The static casts ensure that the virtual function table
- layout of the returned object is correct. */
- if (riid == IID_IUnknown) {
- *ppv = static_cast<IUnknown *> (this);
- } else if (riid == IID_IShellFolder) {
- *ppv = static_cast<IShellFolder*> (this);
- } else {
- log_debug("QueryInterface with unknwon interface: '" GUID_FMT "'",
- GUID_ARG(riid));
- return E_NOINTERFACE;
- }
-
- reinterpret_cast<IUnknown *>(*ppv)->AddRef ();
-
- return S_OK;
+ if (!ppv) {
+ return E_POINTER;
+ }
+
+ log_debug ("Get class object for clsid'" GUID_FMT "'",
+ GUID_ARG(riid));
+ *ppv = nullptr;
+
+ /* The static casts ensure that the virtual function table
+ layout of the returned object is correct. */
+ if (riid == IID_IUnknown) {
+ *ppv = static_cast<IUnknown *> (this);
+ } else if (riid == IID_IShellFolder) {
+ *ppv = static_cast<IShellFolder*> (this);
+ } else if (riid == IID_IPersistFolder ||
+ riid == IID_IPersistFolder2 ||
+ riid == IID_IPersistFolder3 ||
+ riid == IID_IPersist) {
+ return m_persistFolder->QueryInterface (riid, ppv);
+ } else {
+ log_debug("QueryInterface with unknown interface: '" GUID_FMT "'",
+ GUID_ARG(riid));
+ return E_NOINTERFACE;
+ }
+
+ reinterpret_cast<IUnknown *>(*ppv)->AddRef ();
+
+ return S_OK;
}
ULONG STDMETHODCALLTYPE GpgShellFolder::Release()
{
- ULONG lCount = --m_lRef;
- if (!lCount) {
- delete this;
- }
- return lCount;
+ ULONG lCount = --m_lRef;
+ log_debug ("Folder release %i", lCount);
+ if (!lCount) {
+ delete this;
+ }
+ return lCount;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::ParseDisplayName(HWND hwnd,
IBindCtx *pbc,
LPWSTR pszDisplayName,
ULONG *pchEaten,
PIDLIST_RELATIVE *ppidl,
ULONG *pdwAttributes)
{
TRACEPOINT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::EnumObjects(HWND hwnd,
SHCONTF grfFlags,
IEnumIDList **ppenumIDList)
{
TRACEPOINT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::BindToObject(PCUIDLIST_RELATIVE pidl,
IBindCtx *pbc,
REFIID riid,
void **ppv)
{
TRACEPOINT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::BindToStorage(PCUIDLIST_RELATIVE pidl,
IBindCtx *pbc,
REFIID riid,
void **ppv)
{
TRACEPOINT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::CompareIDs(LPARAM lParam,
PCUIDLIST_RELATIVE pidl1,
PCUIDLIST_RELATIVE pidl2)
{
TRACEPOINT;
return S_OK;
}
-HRESULT STDMETHODCALLTYPE GpgShellFolder::CreateViewObject(HWND hwndOwner,
+HRESULT STDMETHODCALLTYPE GpgShellFolder::CreateViewObject(HWND hwnd,
REFIID riid,
void **ppv)
{
TRACEPOINT;
- return S_OK;
+ *ppv = NULL;
+
+ TRACEPOINT;
+ HRESULT hr = E_NOINTERFACE;
+ if (riid == IID_IShellView) {
+ SFV_CREATE csfv = { sizeof(csfv), 0 };
+ hr = QueryInterface(IID_IShellFolder, (void**)&csfv.pshf);
+ if (SUCCEEDED(hr)) {
+ if (SUCCEEDED(hr)) {
+ hr = SHCreateShellFolderView(&csfv, (IShellView**)ppv);
+ csfv.psfvcb->Release();
+ }
+ csfv.pshf->Release();
+ }
+ } else if (riid == IID_ICategoryProvider) {
+ /*
+ CFolderViewImplCategoryProvider* pCatProvider = new (std::nothrow) CFolderViewImplCategoryProvider(this);
+ hr = pCatProvider ? S_OK : E_OUTOFMEMORY;
+ if (SUCCEEDED(hr))
+ {
+ hr = pCatProvider->QueryInterface(riid, ppv);
+ pCatProvider->Release();
+ }
+ */
+ log_debug ("CategoryProvider requested but not implemented.");
+ } else if (riid == IID_IContextMenu){
+ // This is the background context menu for the folder itself, not the context menu on items within it.
+ DEFCONTEXTMENU dcm = { hwnd, NULL, m_persistFolder->pidl(),
+ static_cast<IShellFolder *>(this), // Replace with IShellFolder2
+ 0, NULL, NULL, 0, NULL };
+ hr = SHCreateDefaultContextMenu(&dcm, riid, ppv);
+ } else if (riid == IID_IExplorerCommandProvider) {
+ /*
+ CFolderViewCommandProvider *pProvider = new (std::nothrow) CFolderViewCommandProvider();
+ hr = pProvider ? S_OK : E_OUTOFMEMORY;
+ if (SUCCEEDED(hr))
+ {
+ hr = pProvider->QueryInterface(riid, ppv);
+ pProvider->Release();
+ }
+ */
+ log_debug ("ExplorerCommandProvider requested but not implemented.");
+ } else {
+ log_debug ("nonimp clsid'" GUID_FMT "'",
+ GUID_ARG(riid));
+ }
+ return hr;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::GetAttributesOf(UINT cidl,
PCUITEMID_CHILD_ARRAY apidl,
SFGAOF *rgfInOut)
{
TRACEPOINT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::GetUIObjectOf(HWND hwndOwner,
UINT cidl,
PCUITEMID_CHILD_ARRAY apidl,
REFIID riid,
UINT *rgfReserved,
void **ppv)
{
TRACEPOINT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl,
SHGDNF uFlags,
STRRET *pName)
{
TRACEPOINT;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GpgShellFolder::SetNameOf(HWND hwnd,
PCUITEMID_CHILD pidl,
LPCWSTR pszName,
SHGDNF uFlags,
PITEMID_CHILD *ppidlOut)
{
- TRACEPOINT;
- return S_OK;
+ TRACEPOINT;
+ return S_OK;
}
diff --git a/src/gpga/gpgshellfolder.h b/src/gpga/gpgshellfolder.h
index 4e3ad22..0382b37 100644
--- a/src/gpga/gpgshellfolder.h
+++ b/src/gpga/gpgshellfolder.h
@@ -1,77 +1,80 @@
#ifndef GPGSHELLFOLDER_H
#define GPGSHELLFOLDER_H
/* Copyright (C) 2018 by Andre Heinecke <aheinecke@gnupg.com>
*
* This file is Free Software under the GNU GPL (v>=2)
* and comes with ABSOLUTELY NO WARRANTY!
* See LICENSE.txt for details.
*/
#include <windows.h>
#include <shlobj.h>
+class GpgPersistFolder;
+
class GpgShellFolder: public IShellFolder
{
public:
- GpgShellFolder(): m_lRef(0) {}
+ GpgShellFolder();
virtual ~GpgShellFolder();
/* IUnknown */
STDMETHODIMP QueryInterface (REFIID riid, LPVOID* ppvObj);
STDMETHODIMP_(ULONG) AddRef() { ++m_lRef; return m_lRef; };
STDMETHODIMP_(ULONG) Release();
/* IShellFolder*/
HRESULT STDMETHODCALLTYPE ParseDisplayName(HWND hwnd,
IBindCtx *pbc,
LPWSTR pszDisplayName,
ULONG *pchEaten,
PIDLIST_RELATIVE *ppidl,
ULONG *pdwAttributes);
HRESULT STDMETHODCALLTYPE EnumObjects(HWND hwnd,
SHCONTF grfFlags,
IEnumIDList **ppenumIDList);
HRESULT STDMETHODCALLTYPE BindToObject(PCUIDLIST_RELATIVE pidl,
IBindCtx *pbc,
REFIID riid,
void **ppv);
HRESULT STDMETHODCALLTYPE BindToStorage(PCUIDLIST_RELATIVE pidl,
IBindCtx *pbc,
REFIID riid,
void **ppv);
HRESULT STDMETHODCALLTYPE CompareIDs(LPARAM lParam,
PCUIDLIST_RELATIVE pidl1,
PCUIDLIST_RELATIVE pidl2);
HRESULT STDMETHODCALLTYPE CreateViewObject(HWND hwndOwner,
REFIID riid,
void **ppv);
HRESULT STDMETHODCALLTYPE GetAttributesOf(UINT cidl,
PCUITEMID_CHILD_ARRAY apidl,
SFGAOF *rgfInOut);
HRESULT STDMETHODCALLTYPE GetUIObjectOf(HWND hwndOwner,
UINT cidl,
PCUITEMID_CHILD_ARRAY apidl,
REFIID riid,
UINT *rgfReserved,
void **ppv);
HRESULT STDMETHODCALLTYPE GetDisplayNameOf(PCUITEMID_CHILD pidl,
SHGDNF uFlags,
STRRET *pName);
HRESULT STDMETHODCALLTYPE SetNameOf(HWND hwnd,
PCUITEMID_CHILD pidl,
LPCWSTR pszName,
SHGDNF uFlags,
PITEMID_CHILD *ppidlOut);
private:
ULONG m_lRef;
+ GpgPersistFolder *m_persistFolder;
};
#endif // GPGSHELLFOLDER_H
diff --git a/src/util/debug.h b/src/util/debug.h
index 5d6257a..92571c3 100644
--- a/src/util/debug.h
+++ b/src/util/debug.h
@@ -1,31 +1,33 @@
#ifndef GPG4WIN_DEBUG_H
#define GPG4WIN_DEBUG_H
/* Copyright (C) 2018 by Andre Heinecke <aheinecke@gnupg.com>
*
* This file is Free Software under the GNU GPL (v>=2)
* and comes with ABSOLUTELY NO WARRANTY!
* See LICENSE.txt for details.
*/
#include <gpg-error.h>
const char *log_srcname (const char *s);
#define SRCNAME log_srcname (__FILE__)
#define log_debug(format, ...) \
- gpgrt_log_debug("%s:%s: " format, SRCNAME, __func__, ##__VA_ARGS__)
+ gpgrt_log_debug("%s:%s: " format, SRCNAME, __func__, ##__VA_ARGS__); \
+ gpgrt_log_debug("");
-#define STRANGEPOINT log_debug ("%s:%s:%d:UNEXPECTED", \
+#define STRANGEPOINT log_debug ("%d:UNEXPECTED", \
__LINE__);
-#define TRACEPOINT log_debug ("%s:%s:%d:TRACE");
+#define TRACEPOINT log_debug ("%d:TRACE", \
+ __LINE__);
#define GUID_FMT "{%08lX-%04hX-%04hX-%02hX%02hX-%02hX%02hX%02hX%02hX%02hX%02hX}"
#define GUID_ARG(x) (x).Data1, (x).Data2, (x).Data3, (x).Data4[0], \
(x).Data4[1], (x).Data4[2], (x).Data4[3], (x).Data4[4], \
(x).Data4[5], (x).Data4[6], (x).Data4[7]
#endif // GPG4WIN_DEBUG_H

File Metadata

Mime Type
text/x-diff
Expires
Sun, Dec 28, 10:16 PM (6 h, 13 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
2c/64/61cc9c4b2a305ccf0eab4a1c0251

Event Timeline