[BROWSEUI] Accept TypedURLs to CLSID_ACLCustomMRU (#3250)

Related to #3249. IACLCustomMRU has a special case of TypedURLs. The TypedURLs key consists of the registry values of "url1", "url2", "url3" etc instead of "MRUList", "a", "b" etc. CORE-9281
This commit is contained in:
Katayama Hirofumi MZ 2020-10-02 21:27:23 +09:00 committed by GitHub
parent 434fa562ce
commit bb8cb671b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 142 additions and 7 deletions

View file

@ -3,27 +3,77 @@
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Custom MRU AutoComplete List
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
* Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#include "precomp.h"
#define TYPED_URLS_KEY L"Software\\Microsoft\\Internet Explorer\\TypedURLs"
CACLCustomMRU::CACLCustomMRU()
:m_bDirty(false)
: m_bDirty(false), m_bTypedURLs(FALSE), m_ielt(0)
{
}
CACLCustomMRU::~CACLCustomMRU()
{
PersistMRU();
m_Key.Close();
}
STDMETHODIMP CACLCustomMRU::Next(ULONG celt, LPWSTR *rgelt, ULONG *pceltFetched)
{
if (!pceltFetched || !rgelt)
return E_POINTER;
*pceltFetched = 0;
if (celt == 0)
return S_OK;
*rgelt = NULL;
if (INT(m_ielt) >= m_MRUData.GetSize())
return S_FALSE;
size_t cb = (m_MRUData[m_ielt].GetLength() + 1) * sizeof(WCHAR);
LPWSTR psz = (LPWSTR)CoTaskMemAlloc(cb);
if (!psz)
return S_FALSE;
CopyMemory(psz, (LPCWSTR)m_MRUData[m_ielt], cb);
*rgelt = psz;
*pceltFetched = 1;
++m_ielt;
return S_OK;
}
STDMETHODIMP CACLCustomMRU::Skip(ULONG celt)
{
return E_NOTIMPL;
}
STDMETHODIMP CACLCustomMRU::Reset()
{
m_ielt = 0;
return S_OK;
}
STDMETHODIMP CACLCustomMRU::Clone(IEnumString ** ppenum)
{
*ppenum = NULL;
return E_NOTIMPL;
}
STDMETHODIMP CACLCustomMRU::Expand(LPCOLESTR pszExpand)
{
return E_NOTIMPL;
}
void CACLCustomMRU::PersistMRU()
{
if (!m_bDirty || m_bTypedURLs)
return;
WCHAR Key[2] = { 0, 0 };
if (!m_bDirty)
return;
m_bDirty = false;
if (m_Key.m_hKey)
@ -37,14 +87,78 @@ void CACLCustomMRU::PersistMRU()
}
}
static LSTATUS
RegQueryCStringW(CRegKey& key, LPCWSTR pszValueName, CStringW& str)
{
// Check type and size
DWORD dwType, cbData;
LSTATUS ret = key.QueryValue(pszValueName, &dwType, NULL, &cbData);
if (ret != ERROR_SUCCESS)
return ret;
if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
return ERROR_INVALID_DATA;
// Allocate buffer
LPWSTR pszBuffer = str.GetBuffer(cbData / sizeof(WCHAR) + 1);
if (pszBuffer == NULL)
return ERROR_OUTOFMEMORY;
// Get the data
ret = key.QueryValue(pszValueName, NULL, pszBuffer, &cbData);
// Release buffer
str.ReleaseBuffer();
return ret;
}
HRESULT CACLCustomMRU::LoadTypedURLs(DWORD dwMax)
{
dwMax = max(0, dwMax);
dwMax = min(29, dwMax);
WCHAR szName[32];
CStringW strData;
LSTATUS status;
for (DWORD i = 1; i <= dwMax; ++i)
{
// Build a registry value name
StringCbPrintfW(szName, sizeof(szName), L"url%lu", i);
// Read a registry value
status = RegQueryCStringW(m_Key, szName, strData);
if (status != ERROR_SUCCESS)
break;
m_MRUData.Add(strData);
}
return S_OK;
}
// *** IACLCustomMRU methods ***
HRESULT STDMETHODCALLTYPE CACLCustomMRU::Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax)
{
m_ielt = 0;
LSTATUS Status = m_Key.Create(HKEY_CURRENT_USER, pwszMRURegKey);
if (Status != ERROR_SUCCESS)
return HRESULT_FROM_WIN32(Status);
m_MRUData.RemoveAll();
if (lstrcmpiW(pwszMRURegKey, TYPED_URLS_KEY) == 0)
{
m_bTypedURLs = TRUE;
return LoadTypedURLs(dwMax);
}
else
{
m_bTypedURLs = FALSE;
return LoadMRUList(dwMax);
}
}
HRESULT CACLCustomMRU::LoadMRUList(DWORD dwMax)
{
dwMax = max(0, dwMax);
dwMax = min(29, dwMax);
while (dwMax--)
@ -53,7 +167,7 @@ HRESULT STDMETHODCALLTYPE CACLCustomMRU::Initialize(LPCWSTR pwszMRURegKey, DWORD
WCHAR MRUList[40];
ULONG nChars = _countof(MRUList);
Status = m_Key.QueryStringValue(L"MRUList", MRUList, &nChars);
LSTATUS Status = m_Key.QueryStringValue(L"MRUList", MRUList, &nChars);
if (Status != ERROR_SUCCESS)
return S_OK;
@ -92,6 +206,9 @@ HRESULT STDMETHODCALLTYPE CACLCustomMRU::AddMRUString(LPCWSTR pwszEntry)
{
ATLASSERT(m_MRUData.GetSize() <= m_MRUList.GetLength());
if (m_bTypedURLs)
return E_FAIL;
m_bDirty = true;
CStringW NewElement = pwszEntry;

View file

@ -3,6 +3,7 @@
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Custom MRU AutoComplete List
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
* Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#pragma once
@ -10,6 +11,8 @@
class CACLCustomMRU :
public CComCoClass<CACLCustomMRU, &CLSID_ACLCustomMRU>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IEnumString,
public IACList,
public IACLCustomMRU
{
private:
@ -17,16 +20,29 @@ private:
CStringW m_MRUList;
CSimpleArray<CStringW> m_MRUData;
bool m_bDirty;
BOOL m_bTypedURLs;
ULONG m_ielt;
void PersistMRU();
HRESULT LoadTypedURLs(DWORD dwMax);
HRESULT LoadMRUList(DWORD dwMax);
public:
CACLCustomMRU();
~CACLCustomMRU();
// *** IEnumString methods ***
STDMETHODIMP Next(ULONG celt, LPWSTR *rgelt, ULONG *pceltFetched) override;
STDMETHODIMP Skip(ULONG celt) override;
STDMETHODIMP Reset() override;
STDMETHODIMP Clone(IEnumString ** ppenum) override;
// *** IACList methods ***
STDMETHODIMP Expand(LPCOLESTR pszExpand) override;
// *** IACLCustomMRU methods ***
virtual HRESULT STDMETHODCALLTYPE Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax);
virtual HRESULT STDMETHODCALLTYPE AddMRUString(LPCWSTR pwszEntry);
STDMETHODIMP Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax) override;
STDMETHODIMP AddMRUString(LPCWSTR pwszEntry) override;
public:
@ -36,6 +52,8 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CACLCustomMRU)
COM_INTERFACE_ENTRY_IID(IID_IEnumString, IEnumString)
COM_INTERFACE_ENTRY_IID(IID_IACList, IACList)
COM_INTERFACE_ENTRY_IID(IID_IACLCustomMRU, IACLCustomMRU)
END_COM_MAP()
};