2015-01-22 20:44:54 +03:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2015 Daniel Molkentin <danimo@owncloud.com>. All rights reserved.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or modify it under
|
|
|
|
* the terms of the GNU Lesser General Public License as published by the Free
|
|
|
|
* Software Foundation; either version 2.1 of the License, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This library 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 Lesser General Public License for more
|
|
|
|
* details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
|
|
#include "OCContextMenuRegHandler.h"
|
2015-02-04 21:55:15 +03:00
|
|
|
#include "RegDelnode.h"
|
2015-01-22 20:44:54 +03:00
|
|
|
#include <strsafe.h>
|
|
|
|
#include <objbase.h>
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
HRESULT SetHKCRRegistryKeyAndValue(PCWSTR pszSubKey, PCWSTR pszValueName, PCWSTR pszData)
|
|
|
|
{
|
2017-01-05 19:28:28 +03:00
|
|
|
HRESULT hr;
|
2020-06-05 01:51:32 +03:00
|
|
|
HKEY hKey = nullptr;
|
2017-01-05 19:28:28 +03:00
|
|
|
|
|
|
|
// Creates the specified registry key. If the key already exists, the
|
|
|
|
// function opens it.
|
|
|
|
hr = HRESULT_FROM_WIN32(RegCreateKeyEx(HKEY_CLASSES_ROOT, pszSubKey, 0,
|
2020-06-05 01:51:32 +03:00
|
|
|
nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &hKey, nullptr));
|
2017-01-05 19:28:28 +03:00
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2020-06-05 01:51:32 +03:00
|
|
|
if (pszData != nullptr)
|
2017-01-05 19:28:28 +03:00
|
|
|
{
|
|
|
|
// Set the specified value of the key.
|
|
|
|
DWORD cbData = lstrlen(pszData) * sizeof(*pszData);
|
|
|
|
hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, pszValueName, 0,
|
|
|
|
REG_SZ, reinterpret_cast<const BYTE *>(pszData), cbData));
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2015-01-22 20:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT GetHKCRRegistryKeyAndValue(PCWSTR pszSubKey, PCWSTR pszValueName, PWSTR pszData, DWORD cbData)
|
|
|
|
{
|
2017-01-05 19:28:28 +03:00
|
|
|
HRESULT hr;
|
2020-06-05 01:51:32 +03:00
|
|
|
HKEY hKey = nullptr;
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
// Try to open the specified registry key.
|
|
|
|
hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CLASSES_ROOT, pszSubKey, 0,
|
|
|
|
KEY_READ, &hKey));
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
// Get the data for the specified value name.
|
2020-06-05 01:51:32 +03:00
|
|
|
hr = HRESULT_FROM_WIN32(RegQueryValueEx(hKey, pszValueName, nullptr,
|
|
|
|
nullptr, reinterpret_cast<LPBYTE>(pszData), &cbData));
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
return hr;
|
2015-01-22 20:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT OCContextMenuRegHandler::RegisterInprocServer(PCWSTR pszModule, const CLSID& clsid, PCWSTR pszFriendlyName, PCWSTR pszThreadModel)
|
|
|
|
{
|
2020-06-05 01:51:32 +03:00
|
|
|
if (pszModule == nullptr || pszThreadModel == nullptr)
|
2017-01-05 19:28:28 +03:00
|
|
|
{
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
wchar_t szCLSID[MAX_PATH];
|
|
|
|
StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
|
|
|
|
|
|
|
|
wchar_t szSubkey[MAX_PATH];
|
|
|
|
|
|
|
|
// Create the HKCR\CLSID\{<CLSID>} key.
|
|
|
|
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2020-06-05 01:51:32 +03:00
|
|
|
hr = SetHKCRRegistryKeyAndValue(szSubkey, nullptr, pszFriendlyName);
|
2017-01-05 19:28:28 +03:00
|
|
|
|
|
|
|
// Create the HKCR\CLSID\{<CLSID>}\InprocServer32 key.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
|
|
|
|
L"CLSID\\%s\\InprocServer32", szCLSID);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
// Set the default value of the InprocServer32 key to the
|
|
|
|
// path of the COM module.
|
2020-06-05 01:51:32 +03:00
|
|
|
hr = SetHKCRRegistryKeyAndValue(szSubkey, nullptr, pszModule);
|
2017-01-05 19:28:28 +03:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
// Set the threading model of the component.
|
|
|
|
hr = SetHKCRRegistryKeyAndValue(szSubkey,
|
|
|
|
L"ThreadingModel", pszThreadModel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2015-01-22 20:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT OCContextMenuRegHandler::UnregisterInprocServer(const CLSID& clsid)
|
|
|
|
{
|
2017-01-05 19:28:28 +03:00
|
|
|
HRESULT hr = S_OK;
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
wchar_t szCLSID[MAX_PATH];
|
|
|
|
StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
wchar_t szSubkey[MAX_PATH];
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
// Delete the HKCR\CLSID\{<CLSID>} key.
|
|
|
|
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = HRESULT_FROM_WIN32(RegDelnode(HKEY_CLASSES_ROOT, szSubkey));
|
|
|
|
}
|
2015-01-22 20:44:54 +03:00
|
|
|
|
2017-01-05 19:28:28 +03:00
|
|
|
return hr;
|
2015-01-22 20:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT OCContextMenuRegHandler::RegisterShellExtContextMenuHandler(
|
2017-01-05 19:28:28 +03:00
|
|
|
PCWSTR pszFileType, const CLSID& clsid, PCWSTR pszFriendlyName)
|
2015-01-22 20:44:54 +03:00
|
|
|
{
|
2020-06-05 01:51:32 +03:00
|
|
|
if (pszFileType == nullptr)
|
2017-01-05 19:28:28 +03:00
|
|
|
{
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
wchar_t szCLSID[MAX_PATH];
|
|
|
|
StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
|
|
|
|
|
|
|
|
wchar_t szSubkey[MAX_PATH];
|
|
|
|
|
|
|
|
// If pszFileType starts with '.', try to read the default value of the
|
|
|
|
// HKCR\<File Type> key which contains the ProgID to which the file type
|
|
|
|
// is linked.
|
|
|
|
if (*pszFileType == L'.')
|
|
|
|
{
|
|
|
|
wchar_t szDefaultVal[260];
|
2020-06-05 01:51:32 +03:00
|
|
|
hr = GetHKCRRegistryKeyAndValue(pszFileType, nullptr, szDefaultVal,
|
2017-01-05 19:28:28 +03:00
|
|
|
sizeof(szDefaultVal));
|
|
|
|
|
|
|
|
// If the key exists and its default value is not empty, use the
|
|
|
|
// ProgID as the file type.
|
|
|
|
if (SUCCEEDED(hr) && szDefaultVal[0] != L'\0')
|
|
|
|
{
|
|
|
|
pszFileType = szDefaultVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the key HKCR\<File Type>\shellex\ContextMenuHandlers\{friendlyName>}
|
|
|
|
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
|
|
|
|
L"%s\\shellex\\ContextMenuHandlers\\%s", pszFileType, pszFriendlyName);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
// Set the default value of the key.
|
2020-06-05 01:51:32 +03:00
|
|
|
hr = SetHKCRRegistryKeyAndValue(szSubkey, nullptr, szCLSID);
|
2017-01-05 19:28:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2015-01-22 20:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT OCContextMenuRegHandler::UnregisterShellExtContextMenuHandler(
|
2017-01-05 19:28:28 +03:00
|
|
|
PCWSTR pszFileType, PCWSTR pszFriendlyName)
|
2015-01-22 20:44:54 +03:00
|
|
|
{
|
2020-06-05 01:51:32 +03:00
|
|
|
if (pszFileType == nullptr)
|
2017-01-05 19:28:28 +03:00
|
|
|
{
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
wchar_t szSubkey[MAX_PATH];
|
|
|
|
|
|
|
|
// If pszFileType starts with '.', try to read the default value of the
|
|
|
|
// HKCR\<File Type> key which contains the ProgID to which the file type
|
|
|
|
// is linked.
|
|
|
|
if (*pszFileType == L'.')
|
|
|
|
{
|
|
|
|
wchar_t szDefaultVal[260];
|
2020-06-05 01:51:32 +03:00
|
|
|
hr = GetHKCRRegistryKeyAndValue(pszFileType, nullptr, szDefaultVal,
|
2017-01-05 19:28:28 +03:00
|
|
|
sizeof(szDefaultVal));
|
|
|
|
|
|
|
|
// If the key exists and its default value is not empty, use the
|
|
|
|
// ProgID as the file type.
|
|
|
|
if (SUCCEEDED(hr) && szDefaultVal[0] != L'\0')
|
|
|
|
{
|
|
|
|
pszFileType = szDefaultVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the HKCR\<File Type>\shellex\ContextMenuHandlers\{friendlyName} key.
|
|
|
|
hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
|
|
|
|
L"%s\\shellex\\ContextMenuHandlers\\%s", pszFileType, pszFriendlyName);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = HRESULT_FROM_WIN32(RegDelnode(HKEY_CLASSES_ROOT, szSubkey));
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2020-06-05 01:51:32 +03:00
|
|
|
}
|