From 001deace2d5cc9c0c4bcf782ac21f42fe17177d7 Mon Sep 17 00:00:00 2001 From: alex-z Date: Mon, 4 Jul 2022 15:36:06 +0300 Subject: Implement COM Dll for CfApi shell extensins. Implement Thumbnail Provider. Signed-off-by: alex-z --- src/common/filesystembase.h | 2 +- src/common/shellextensionutils.cpp | 36 ++++++++++++++++++++++++++++ src/common/shellextensionutils.h | 35 +++++++++++++++++++++++++++ src/common/utility.h | 3 ++- src/common/utility_win.cpp | 49 +++++++++++++++++++++++++++++++++++++- src/common/vfs.h | 3 +++ 6 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 src/common/shellextensionutils.cpp create mode 100644 src/common/shellextensionutils.h (limited to 'src/common') diff --git a/src/common/filesystembase.h b/src/common/filesystembase.h index b15cb4fa1..bc0b592c2 100644 --- a/src/common/filesystembase.h +++ b/src/common/filesystembase.h @@ -25,7 +25,7 @@ #include #include -#include +#include class QFile; diff --git a/src/common/shellextensionutils.cpp b/src/common/shellextensionutils.cpp new file mode 100644 index 000000000..d6f4b244c --- /dev/null +++ b/src/common/shellextensionutils.cpp @@ -0,0 +1,36 @@ +#include "shellextensionutils.h" +#include +#include + +namespace VfsShellExtensions { + +Q_LOGGING_CATEGORY(lcShellExtensionUtils, "nextcloud.gui.shellextensionutils", QtInfoMsg) + +QString VfsShellExtensions::serverNameForApplicationName(const QString &applicationName) +{ + return applicationName + QStringLiteral(":VfsShellExtensionsServer"); +} + +QString VfsShellExtensions::serverNameForApplicationNameDefault() +{ + return serverNameForApplicationName(APPLICATION_NAME); +} +namespace Protocol { + QByteArray createJsonMessage(const QVariantMap &message) + { + QVariantMap messageCopy = message; + messageCopy[QStringLiteral("version")] = Version; + return QJsonDocument::fromVariant((messageCopy)).toJson(QJsonDocument::Compact); + } + + bool validateProtocolVersion(const QVariantMap &message) + { + const auto valid = message.value(QStringLiteral("version")) == Version; + if (!valid) { + qCWarning(lcShellExtensionUtils) << "Invalid shell extensions IPC protocol: " << message.value(QStringLiteral("version")) << " vs " << Version; + } + Q_ASSERT(valid); + return valid; + } +} +} diff --git a/src/common/shellextensionutils.h b/src/common/shellextensionutils.h new file mode 100644 index 000000000..ca0d9922d --- /dev/null +++ b/src/common/shellextensionutils.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#pragma once +#include "config.h" +#include +#include +#include + +namespace VfsShellExtensions { +QString serverNameForApplicationName(const QString &applicationName); +QString serverNameForApplicationNameDefault(); + +namespace Protocol { + static constexpr auto ThumbnailProviderRequestKey = "thumbnailProviderRequest"; + static constexpr auto ThumbnailProviderRequestFilePathKey = "filePath"; + static constexpr auto ThumbnailProviderRequestFileSizeKey = "fileSize"; + static constexpr auto ThumnailProviderDataKey = "thumbnailData"; + static constexpr auto Version = "1.0"; + + QByteArray createJsonMessage(const QVariantMap &message); + bool validateProtocolVersion(const QVariantMap &message); +} +} diff --git a/src/common/utility.h b/src/common/utility.h index 45df7f647..98dc3030a 100644 --- a/src/common/utility.h +++ b/src/common/utility.h @@ -21,7 +21,7 @@ #define UTILITY_H -#include "ocsynclib.h" +#include "csync/ocsynclib.h" #include #include #include @@ -254,6 +254,7 @@ namespace Utility { OCSYNC_EXPORT bool registryDeleteKeyTree(HKEY hRootKey, const QString &subKey); OCSYNC_EXPORT bool registryDeleteKeyValue(HKEY hRootKey, const QString &subKey, const QString &valueName); OCSYNC_EXPORT bool registryWalkSubKeys(HKEY hRootKey, const QString &subKey, const std::function &callback); + OCSYNC_EXPORT bool registryWalkValues(HKEY hRootKey, const QString &subKey, const std::function &callback); OCSYNC_EXPORT QRect getTaskbarDimensions(); // Possibly refactor to share code with UnixTimevalToFileTime in c_time.c diff --git a/src/common/utility_win.cpp b/src/common/utility_win.cpp index 80907ea5d..ed322669b 100644 --- a/src/common/utility_win.cpp +++ b/src/common/utility_win.cpp @@ -28,8 +28,11 @@ #include #include #include - +#include +#include +#include #include +#include extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; @@ -354,6 +357,50 @@ bool Utility::registryWalkSubKeys(HKEY hRootKey, const QString &subKey, const st return retCode != ERROR_NO_MORE_ITEMS; } +bool Utility::registryWalkValues(HKEY hRootKey, const QString &subKey, const std::function &callback) +{ + HKEY hKey; + REGSAM sam = KEY_QUERY_VALUE; + LONG result = RegOpenKeyEx(hRootKey, reinterpret_cast(subKey.utf16()), 0, sam, &hKey); + ASSERT(result == ERROR_SUCCESS); + if (result != ERROR_SUCCESS) { + return false; + } + + DWORD maxValueNameSize = 0; + result = RegQueryInfoKey(hKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &maxValueNameSize, nullptr, nullptr, nullptr); + ASSERT(result == ERROR_SUCCESS); + if (result != ERROR_SUCCESS) { + RegCloseKey(hKey); + return false; + } + + QString valueName; + valueName.reserve(maxValueNameSize + 1); + + DWORD retCode = ERROR_SUCCESS; + bool done = false; + for (DWORD i = 0; retCode == ERROR_SUCCESS; ++i) { + Q_ASSERT(unsigned(valueName.capacity()) > maxValueNameSize); + valueName.resize(valueName.capacity()); + DWORD valueNameSize = valueName.size(); + retCode = RegEnumValue(hKey, i, reinterpret_cast(valueName.data()), &valueNameSize, nullptr, nullptr, nullptr, nullptr); + + ASSERT(result == ERROR_SUCCESS || retCode == ERROR_NO_MORE_ITEMS); + if (retCode == ERROR_SUCCESS) { + valueName.resize(valueNameSize); + callback(valueName, &done); + + if (done) { + break; + } + } + } + + RegCloseKey(hKey); + return retCode != ERROR_NO_MORE_ITEMS; +} + DWORD Utility::convertSizeToDWORD(size_t &convertVar) { if( convertVar > UINT_MAX ) { diff --git a/src/common/vfs.h b/src/common/vfs.h index 19160e341..572c297a4 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -49,6 +49,9 @@ struct OCSYNC_EXPORT VfsSetupParams // Folder alias QString alias; + // Folder registry navigation Pane CLSID + QString navigationPaneClsid; + /** The path to the synced folder on the account * * Always ends with /. -- cgit v1.2.3