ReactOS  0.4.15-dev-1392-g3014417
ACLCustomMRU.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS browseui
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Custom MRU AutoComplete List
5  * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6  * Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7  */
8 
9 #include "precomp.h"
10 
11 #define TYPED_URLS_KEY L"Software\\Microsoft\\Internet Explorer\\TypedURLs"
12 
14  : m_bDirty(false), m_bTypedURLs(FALSE), m_ielt(0)
15 {
16 }
17 
19 {
20  PersistMRU();
21 }
22 
23 STDMETHODIMP CACLCustomMRU::Next(ULONG celt, LPWSTR *rgelt, ULONG *pceltFetched)
24 {
25  if (!pceltFetched || !rgelt)
26  return E_POINTER;
27 
28  *pceltFetched = 0;
29  if (celt == 0)
30  return S_OK;
31 
32  *rgelt = NULL;
33  if (INT(m_ielt) >= m_MRUData.GetSize())
34  return S_FALSE;
35 
37 
38  if (!m_bTypedURLs)
39  {
40  // Erase the last "\\1" etc. (indicates SW_* value)
41  INT ich = str.ReverseFind(L'\\');
42  if (ich >= 0)
43  str = str.Left(ich);
44  }
45 
46  size_t cb = (str.GetLength() + 1) * sizeof(WCHAR);
48  if (!psz)
49  return S_FALSE;
50 
51  CopyMemory(psz, (LPCWSTR)str, cb);
52  *rgelt = psz;
53  *pceltFetched = 1;
54  ++m_ielt;
55  return S_OK;
56 }
57 
59 {
60  return E_NOTIMPL;
61 }
62 
64 {
65  m_ielt = 0;
66  return S_OK;
67 }
68 
70 {
71  *ppenum = NULL;
72  return E_NOTIMPL;
73 }
74 
75 STDMETHODIMP CACLCustomMRU::Expand(LPCOLESTR pszExpand)
76 {
77  return E_NOTIMPL;
78 }
79 
81 {
82  if (!m_bDirty || m_bTypedURLs)
83  return;
84 
85  WCHAR Key[2] = { 0, 0 };
86 
87  m_bDirty = false;
88 
89  if (m_Key.m_hKey)
90  {
91  m_Key.SetStringValue(L"MRUList", m_MRUList);
92  for (int Index = 0; Index < m_MRUList.GetLength(); ++Index)
93  {
94  Key[0] = Index + 'a';
96  }
97  }
98 }
99 
100 static LSTATUS
102 {
103  // Check type and size
104  DWORD dwType, cbData;
105  LSTATUS ret = key.QueryValue(pszValueName, &dwType, NULL, &cbData);
106  if (ret != ERROR_SUCCESS)
107  return ret;
108  if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
109  return ERROR_INVALID_DATA;
110 
111  // Allocate buffer
112  LPWSTR pszBuffer = str.GetBuffer(cbData / sizeof(WCHAR) + 1);
113  if (pszBuffer == NULL)
114  return ERROR_OUTOFMEMORY;
115 
116  // Get the data
117  ret = key.QueryValue(pszValueName, NULL, pszBuffer, &cbData);
118 
119  // Release buffer
120  str.ReleaseBuffer();
121  return ret;
122 }
123 
125 {
126  dwMax = max(0, dwMax);
127  dwMax = min(29, dwMax);
128 
129  WCHAR szName[32];
130  CStringW strData;
131  LSTATUS status;
132  for (DWORD i = 1; i <= dwMax; ++i)
133  {
134  // Build a registry value name
135  StringCbPrintfW(szName, sizeof(szName), L"url%lu", i);
136 
137  // Read a registry value
138  status = RegQueryCStringW(m_Key, szName, strData);
139  if (status != ERROR_SUCCESS)
140  break;
141 
142  m_MRUData.Add(strData);
143  }
144 
145  return S_OK;
146 }
147 
148 // *** IACLCustomMRU methods ***
150 {
151  m_ielt = 0;
152 
153  LSTATUS Status = m_Key.Create(HKEY_CURRENT_USER, pwszMRURegKey);
154  if (Status != ERROR_SUCCESS)
155  return HRESULT_FROM_WIN32(Status);
156 
158  if (lstrcmpiW(pwszMRURegKey, TYPED_URLS_KEY) == 0)
159  {
160  m_bTypedURLs = TRUE;
161  return LoadTypedURLs(dwMax);
162  }
163  else
164  {
166  return LoadMRUList(dwMax);
167  }
168 }
169 
171 {
172  dwMax = max(0, dwMax);
173  dwMax = min(29, dwMax);
174  while (dwMax--)
176 
177  WCHAR MRUList[40];
178  ULONG nChars = _countof(MRUList);
179 
180  LSTATUS Status = m_Key.QueryStringValue(L"MRUList", MRUList, &nChars);
181  if (Status != ERROR_SUCCESS)
182  return S_OK;
183 
184  if (nChars > 0 && MRUList[nChars-1] == '\0')
185  nChars--;
186 
187  if (nChars > (ULONG)m_MRUData.GetSize())
188  return S_OK;
189 
190  for (ULONG n = 0; n < nChars; ++n)
191  {
192  if (MRUList[n] >= 'a' && MRUList[n] <= '}' && m_MRUList.Find(MRUList[n]) < 0)
193  {
194  WCHAR Key[2] = { MRUList[n], NULL };
195  WCHAR Value[MAX_PATH * 2];
196  ULONG nValueChars = _countof(Value);
197 
198  m_MRUList += MRUList[n];
199  int Index = MRUList[n] - 'a';
200 
201  if (Index < m_MRUData.GetSize())
202  {
203  Status = m_Key.QueryStringValue(Key, Value, &nValueChars);
204  if (Status == ERROR_SUCCESS)
205  {
206  m_MRUData[Index] = CStringW(Value, nValueChars);
207  }
208  }
209  }
210  }
211 
212  return S_OK;
213 }
214 
216 {
217  if (m_bTypedURLs)
218  return E_FAIL;
219 
221  m_bDirty = true;
222 
223  CStringW NewElement = pwszEntry;
224  WCHAR Key[2] = { 0, 0 };
225  int Index = m_MRUData.Find(NewElement);
226  if (Index >= 0)
227  {
228  /* Move the key to the front */
229  Key[0] = Index + 'a';
230  m_MRUList.Replace(Key, L"");
231  m_MRUList = Key + m_MRUList;
232  return S_OK;
233  }
234 
235  int TotalLen = m_MRUList.GetLength();
236  if (m_MRUData.GetSize() == TotalLen)
237  {
238  /* Find oldest element, move that to the front */
239  Key[0] = m_MRUList[TotalLen-1];
240  m_MRUList = Key + m_MRUList.Left(TotalLen-1);
241  Index = Key[0] - 'a';
242  }
243  else
244  {
245  /* Find the first empty entry */
246  for (Index = 0; Index < m_MRUData.GetSize(); ++Index)
247  {
248  if (m_MRUData[Index].IsEmpty())
249  break;
250  }
251  Key[0] = Index + 'a';
252  m_MRUList = Key + m_MRUList;
253  }
254  m_MRUData[Index] = NewElement;
255 
256  PersistMRU();
257  return S_OK;
258 }
259 
int GetLength() const
Definition: atlsimpstr.h:356
#define max(a, b)
Definition: svc.c:63
HRESULT LoadTypedURLs(DWORD dwMax)
STDMETHODIMP AddMRUString(LPCWSTR pwszEntry) override
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
BOOL Add(const T &t)
Definition: atlsimpcoll.h:58
#define TYPED_URLS_KEY
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
#define TRUE
Definition: types.h:120
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define INT
Definition: polytest.cpp:20
GLdouble n
Definition: glext.h:7729
STDMETHODIMP Next(ULONG celt, LPWSTR *rgelt, ULONG *pceltFetched) override
CSimpleArray< CStringW > m_MRUData
Definition: ACLCustomMRU.h:21
STDMETHODIMP Clone(IEnumString **ppenum) override
#define E_FAIL
Definition: ddrawi.h:102
int GetSize() const
Definition: atlsimpcoll.h:104
int32_t INT
Definition: typedefs.h:58
HKEY m_hKey
Definition: atlbase.h:1013
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define FALSE
Definition: types.h:117
#define STDMETHODIMP
Definition: basetyps.h:43
#define S_FALSE
Definition: winerror.h:2357
const WCHAR * str
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
#define false
Definition: osdep.h:35
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
_In_ WDFCOLLECTION _In_ ULONG Index
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
#define CopyMemory
Definition: winbase.h:1646
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
unsigned long DWORD
Definition: ntddk_ex.h:95
LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG *pnChars)
Definition: atlbase.h:1149
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
STDMETHODIMP Expand(LPCOLESTR pszExpand) override
int ret
static LSTATUS RegQueryCStringW(CRegKey &key, LPCWSTR pszValueName, CStringW &str)
static const WCHAR L[]
Definition: oid.c:1250
STDMETHODIMP Skip(ULONG celt) override
LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName, LPTSTR lpszClass=REG_NONE, DWORD dwOptions=REG_OPTION_NON_VOLATILE, REGSAM samDesired=KEY_READ|KEY_WRITE, LPSECURITY_ATTRIBUTES lpSecAttr=NULL, LPDWORD lpdwDisposition=NULL)
Definition: atlbase.h:1091
STDMETHODIMP Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax) override
#define ERROR_INVALID_DATA
Definition: winerror.h:116
int Replace(PCXSTR pszOld, PCXSTR pszNew)
Definition: cstringt.h:774
#define S_OK
Definition: intsafe.h:51
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HRESULT LoadMRUList(DWORD dwMax)
STDMETHODIMP Reset() override
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define E_NOTIMPL
Definition: ddrawi.h:99
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
int Find(_In_ PCXSTR pszSub, _In_opt_ int iStart=0) const
Definition: cstringt.h:611
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
static const WCHAR szName[]
Definition: msipriv.h:1194
unsigned int ULONG
Definition: retypes.h:1
CAtlStringW CStringW
Definition: atlstr.h:130
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define E_POINTER
Definition: winerror.h:2365
CRegKey m_Key
Definition: ACLCustomMRU.h:19
static SERVICE_STATUS status
Definition: service.c:31
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
CStringT Left(int nCount) const
Definition: cstringt.h:691
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
Definition: path.c:41
int Find(const T &t) const
Definition: atlsimpcoll.h:82
LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType=REG_SZ)
Definition: atlbase.h:1224
#define REG_SZ
Definition: layer.c:22
CStringW m_MRUList
Definition: ACLCustomMRU.h:20
Definition: ps.c:97