1cba27435SMark Jansen /*
2cba27435SMark Jansen * PROJECT: ReactOS api tests
32eb96f0cSMark Jansen * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4cba27435SMark Jansen * PURPOSE: Test for IACLCustomMRU objects
52eb96f0cSMark Jansen * COPYRIGHT: Copyright 2017-2020 Mark Jansen (mark.jansen@reactos.org)
6cba27435SMark Jansen */
7cba27435SMark Jansen
8cba27435SMark Jansen #define _UNICODE
9cba27435SMark Jansen #define UNICODE
10cba27435SMark Jansen #include <apitest.h>
11cba27435SMark Jansen #include <shlobj.h>
12cba27435SMark Jansen #include <atlbase.h>
13cba27435SMark Jansen #include <atlstr.h>
14cba27435SMark Jansen #include <atlcom.h>
15cba27435SMark Jansen #include <atlwin.h>
16cba27435SMark Jansen
17cba27435SMark Jansen // Yes, gcc at it again, let's validate everything found inside unused templates!
18cba27435SMark Jansen ULONG DbgPrint(PCH Format,...);
19cba27435SMark Jansen
20cba27435SMark Jansen #include <shellutils.h>
21cba27435SMark Jansen #include <shlwapi.h>
22cba27435SMark Jansen #include <strsafe.h>
23cba27435SMark Jansen #include <initguid.h>
24cba27435SMark Jansen
252eb96f0cSMark Jansen #define ok_hex2(file, line, key, expression, result) \
26cba27435SMark Jansen do { \
27cba27435SMark Jansen int _value = (expression); \
28cba27435SMark Jansen ok_(file, line)(_value == (result), "Wrong value for '%s', expected: " #result " (0x%x), got: 0x%x for %c\n", \
29cba27435SMark Jansen #expression, (int)(result), _value, (char)key); \
30cba27435SMark Jansen } while (0)
31cba27435SMark Jansen
32b1c33293SKatayama Hirofumi MZ #define ok_wstri(x, y) \
33b1c33293SKatayama Hirofumi MZ ok(lstrcmpiW(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x)
34cba27435SMark Jansen
35cba27435SMark Jansen
36cba27435SMark Jansen DEFINE_GUID(IID_IACLCustomMRU, 0xf729fc5e, 0x8769, 0x4f3e, 0xbd, 0xb2, 0xd7, 0xb5, 0x0f, 0xd2, 0x27, 0x5b);
37cba27435SMark Jansen static const WCHAR szTestPath[] = L"TESTPATH_BROWSEUI_APITEST";
38cba27435SMark Jansen
39cba27435SMark Jansen #undef INTERFACE
40cba27435SMark Jansen #define INTERFACE IACLCustomMRU
41cba27435SMark Jansen
42cba27435SMark Jansen /* based on https://msdn.microsoft.com/en-gb/library/windows/desktop/bb776380(v=vs.85).aspx */
43cba27435SMark Jansen DECLARE_INTERFACE_IID_(IACLCustomMRU, IUnknown, "F729FC5E-8769-4F3E-BDB2-D7B50FD2275B")
44cba27435SMark Jansen {
45cba27435SMark Jansen // *** IUnknown methods ***
46cba27435SMark Jansen STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
47cba27435SMark Jansen STDMETHOD_(ULONG, AddRef) (THIS)PURE;
48cba27435SMark Jansen STDMETHOD_(ULONG, Release) (THIS)PURE;
49cba27435SMark Jansen
50cba27435SMark Jansen // *** IACLCustomMRU methods ***
51cba27435SMark Jansen STDMETHOD(Initialize) (THIS_ LPCWSTR pwszMRURegKey, DWORD dwMax) PURE;
52cba27435SMark Jansen STDMETHOD(AddMRUString) (THIS_ LPCWSTR pwszEntry) PURE;
53cba27435SMark Jansen };
54cba27435SMark Jansen
55cba27435SMark Jansen
Cleanup_Testdata()56cba27435SMark Jansen static void Cleanup_Testdata()
57cba27435SMark Jansen {
58cba27435SMark Jansen CRegKey tmp;
59cba27435SMark Jansen if (!tmp.Open(HKEY_CURRENT_USER, NULL, KEY_READ | KEY_WRITE))
60cba27435SMark Jansen tmp.DeleteSubKey(szTestPath);
61cba27435SMark Jansen }
62cba27435SMark Jansen
63cba27435SMark Jansen #define verify_mru(mru, ...) verify_mru_(__FILE__, __LINE__, mru, __VA_ARGS__, NULL)
verify_mru_(const char * file,int line,IACLCustomMRU * mru,PCWSTR MRUString,...)64cba27435SMark Jansen static void verify_mru_(const char* file, int line, IACLCustomMRU* mru, PCWSTR MRUString, ...)
65cba27435SMark Jansen {
66cba27435SMark Jansen
67cba27435SMark Jansen CRegKey key;
68cba27435SMark Jansen key.Open(HKEY_CURRENT_USER, szTestPath);
69cba27435SMark Jansen
70cba27435SMark Jansen va_list args;
71cba27435SMark Jansen va_start(args, MRUString);
72cba27435SMark Jansen PCWSTR Entry;
73cba27435SMark Jansen WCHAR Key = L'a';
74cba27435SMark Jansen while ((Entry = va_arg(args, PCWSTR)))
75cba27435SMark Jansen {
76cba27435SMark Jansen WCHAR Value[MAX_PATH];
77cba27435SMark Jansen ULONG nChars = _countof(Value);
78cba27435SMark Jansen CStringW tmp;
79cba27435SMark Jansen tmp += Key;
80cba27435SMark Jansen LSTATUS Status = key.QueryStringValue(tmp, Value, &nChars);
812eb96f0cSMark Jansen ok_hex2(file, line, Key, Status, ERROR_SUCCESS);
82cba27435SMark Jansen if (Status == ERROR_SUCCESS)
83cba27435SMark Jansen {
84cba27435SMark Jansen ok_(file, line)(!wcscmp(Value, Entry), "Expected value %c to be %S, was %S\n", (char)Key, Entry, Value);
85cba27435SMark Jansen }
86cba27435SMark Jansen Key++;
87cba27435SMark Jansen }
88cba27435SMark Jansen va_end(args);
89cba27435SMark Jansen
90cba27435SMark Jansen if (Key != L'a')
91cba27435SMark Jansen {
92cba27435SMark Jansen WCHAR Value[MAX_PATH];
93cba27435SMark Jansen ULONG nChars = _countof(Value);
94cba27435SMark Jansen LSTATUS Status = key.QueryStringValue(L"MRUList", Value, &nChars);
952eb96f0cSMark Jansen ok_hex2(file, line, Key, Status, ERROR_SUCCESS);
96cba27435SMark Jansen if (Status == ERROR_SUCCESS)
97cba27435SMark Jansen {
98cba27435SMark Jansen ok_(file, line)(!wcscmp(Value, MRUString), "Expected MRUList to be %S, was %S\n", MRUString, Value);
99cba27435SMark Jansen }
100cba27435SMark Jansen }
101cba27435SMark Jansen }
102cba27435SMark Jansen
103cba27435SMark Jansen
104cba27435SMark Jansen static void
test_IACLCustomMRU_Basics()105cba27435SMark Jansen test_IACLCustomMRU_Basics()
106cba27435SMark Jansen {
107cba27435SMark Jansen CComPtr<IACLCustomMRU> CustomMRU;
108cba27435SMark Jansen HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
109cba27435SMark Jansen ok_hex(hr, S_OK);
110cba27435SMark Jansen if (!SUCCEEDED(hr))
111cba27435SMark Jansen return;
112cba27435SMark Jansen
113cba27435SMark Jansen Cleanup_Testdata();
114cba27435SMark Jansen
115cba27435SMark Jansen /* Initialize with a NULL name will cause an AV */
116cba27435SMark Jansen //hr = CustomMRU->Initialize(NULL, 0);
117cba27435SMark Jansen
118cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 0);
119cba27435SMark Jansen ok_hex(hr, S_OK);
120cba27435SMark Jansen /* Adding an entry with a dwMax of 0 will cause an AV */
121cba27435SMark Jansen
122cba27435SMark Jansen /* Calling it again will resize */
123cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
124cba27435SMark Jansen ok_hex(hr, S_OK);
125cba27435SMark Jansen verify_mru(CustomMRU, L"");
126cba27435SMark Jansen
127cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FIRST_ENTRY");
128cba27435SMark Jansen ok_hex(hr, S_OK);
129cba27435SMark Jansen verify_mru(CustomMRU, L"a", L"FIRST_ENTRY");
130cba27435SMark Jansen
131cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"SECOND_ENTRY");
132cba27435SMark Jansen ok_hex(hr, S_OK);
133cba27435SMark Jansen verify_mru(CustomMRU, L"ba", L"FIRST_ENTRY", L"SECOND_ENTRY");
134cba27435SMark Jansen
135cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"THIRD_ENTRY");
136cba27435SMark Jansen ok_hex(hr, S_OK);
137cba27435SMark Jansen verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
138cba27435SMark Jansen
139cba27435SMark Jansen /* First entry is replaced */
140cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FOURTH_ENTRY");
141cba27435SMark Jansen ok_hex(hr, S_OK);
142cba27435SMark Jansen verify_mru(CustomMRU, L"acb", L"FOURTH_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
143cba27435SMark Jansen
144cba27435SMark Jansen /* Second entry is replaced */
145cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FIFTH_ENTRY");
146cba27435SMark Jansen ok_hex(hr, S_OK);
147cba27435SMark Jansen verify_mru(CustomMRU, L"bac", L"FOURTH_ENTRY", L"FIFTH_ENTRY", L"THIRD_ENTRY");
148cba27435SMark Jansen }
149cba27435SMark Jansen
150cba27435SMark Jansen
FillDefault(IACLCustomMRU * CustomMRU)151cba27435SMark Jansen static void FillDefault(IACLCustomMRU* CustomMRU)
152cba27435SMark Jansen {
153cba27435SMark Jansen Cleanup_Testdata();
154cba27435SMark Jansen HRESULT hr = CustomMRU->Initialize(szTestPath, 3);
155cba27435SMark Jansen ok_hex(hr, S_OK);
156cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FIRST_ENTRY");
157cba27435SMark Jansen ok_hex(hr, S_OK);
158cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"SECOND_ENTRY");
159cba27435SMark Jansen ok_hex(hr, S_OK);
160cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"THIRD_ENTRY");
161cba27435SMark Jansen ok_hex(hr, S_OK);
162cba27435SMark Jansen }
163cba27435SMark Jansen
164cba27435SMark Jansen static void
test_IACLCustomMRU_UpdateOrder()165cba27435SMark Jansen test_IACLCustomMRU_UpdateOrder()
166cba27435SMark Jansen {
167cba27435SMark Jansen CComPtr<IACLCustomMRU> CustomMRU;
168cba27435SMark Jansen HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
169cba27435SMark Jansen ok_hex(hr, S_OK);
170cba27435SMark Jansen if (!SUCCEEDED(hr))
171cba27435SMark Jansen return;
172cba27435SMark Jansen
173cba27435SMark Jansen Cleanup_Testdata();
174cba27435SMark Jansen FillDefault(CustomMRU);
175cba27435SMark Jansen verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
176cba27435SMark Jansen
177cba27435SMark Jansen /* Add the first entry again */
178cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FIRST_ENTRY");
179cba27435SMark Jansen ok_hex(hr, S_OK);
180cba27435SMark Jansen /* No change */
181cba27435SMark Jansen verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
182cba27435SMark Jansen
183cba27435SMark Jansen CustomMRU.Release();
184cba27435SMark Jansen /* Now the order is updated */
185cba27435SMark Jansen verify_mru(NULL, L"acb", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
186cba27435SMark Jansen
187cba27435SMark Jansen
188cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
189cba27435SMark Jansen ok_hex(hr, S_OK);
190cba27435SMark Jansen if (!SUCCEEDED(hr))
191cba27435SMark Jansen return;
192cba27435SMark Jansen
193cba27435SMark Jansen Cleanup_Testdata();
194cba27435SMark Jansen FillDefault(CustomMRU);
195cba27435SMark Jansen verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
196cba27435SMark Jansen
197cba27435SMark Jansen
198cba27435SMark Jansen /* Add the first entry again */
199cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FIRST_ENTRY");
200cba27435SMark Jansen ok_hex(hr, S_OK);
201cba27435SMark Jansen /* No change */
202cba27435SMark Jansen verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
203cba27435SMark Jansen
204cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"SOMETHING_ELSE");
205cba27435SMark Jansen ok_hex(hr, S_OK);
206cba27435SMark Jansen /* Now all changes are persisted */
207cba27435SMark Jansen verify_mru(CustomMRU, L"bac", L"FIRST_ENTRY", L"SOMETHING_ELSE", L"THIRD_ENTRY");
208cba27435SMark Jansen }
209cba27435SMark Jansen
210cba27435SMark Jansen static void
test_IACLCustomMRU_ExtraChars()211cba27435SMark Jansen test_IACLCustomMRU_ExtraChars()
212cba27435SMark Jansen {
213cba27435SMark Jansen CComPtr<IACLCustomMRU> CustomMRU;
214cba27435SMark Jansen HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
215cba27435SMark Jansen ok_hex(hr, S_OK);
216cba27435SMark Jansen if (!SUCCEEDED(hr))
217cba27435SMark Jansen return;
218cba27435SMark Jansen
219cba27435SMark Jansen Cleanup_Testdata();
220cba27435SMark Jansen
221cba27435SMark Jansen /* Still returnes success */
222cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 30);
223cba27435SMark Jansen ok_hex(hr, S_OK);
224cba27435SMark Jansen
225cba27435SMark Jansen for (int n = 0; n < 30; ++n)
226cba27435SMark Jansen {
227cba27435SMark Jansen CStringW tmp;
228cba27435SMark Jansen tmp.Format(L"%d", n);
229cba27435SMark Jansen
230cba27435SMark Jansen hr = CustomMRU->AddMRUString(tmp);
231cba27435SMark Jansen ok_hex(hr, S_OK);
232cba27435SMark Jansen }
233cba27435SMark Jansen /* But is starting to wrap around */
234cba27435SMark Jansen verify_mru(CustomMRU, L"a}|{zyxwvutsrqponmlkjihgfedcb", L"29",
235cba27435SMark Jansen L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9",
236cba27435SMark Jansen L"10", L"11", L"12", L"13", L"14", L"15", L"16", L"17", L"18", L"19",
237cba27435SMark Jansen L"20", L"21", L"22", L"23", L"24", L"25", L"26", L"27", L"28");
238cba27435SMark Jansen
239cba27435SMark Jansen Cleanup_Testdata();
240cba27435SMark Jansen }
241cba27435SMark Jansen
242cba27435SMark Jansen static void
test_IACLCustomMRU_Continue()243cba27435SMark Jansen test_IACLCustomMRU_Continue()
244cba27435SMark Jansen {
245cba27435SMark Jansen CComPtr<IACLCustomMRU> CustomMRU;
246cba27435SMark Jansen HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
247cba27435SMark Jansen ok_hex(hr, S_OK);
248cba27435SMark Jansen if (!SUCCEEDED(hr))
249cba27435SMark Jansen return;
250cba27435SMark Jansen
251cba27435SMark Jansen Cleanup_Testdata();
252cba27435SMark Jansen FillDefault(CustomMRU);
253cba27435SMark Jansen verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
254cba27435SMark Jansen
255cba27435SMark Jansen CustomMRU.Release();
256cba27435SMark Jansen
257cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
258cba27435SMark Jansen ok_hex(hr, S_OK);
259cba27435SMark Jansen if (!SUCCEEDED(hr))
260cba27435SMark Jansen return;
261cba27435SMark Jansen
262cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
263cba27435SMark Jansen ok_hex(hr, S_OK);
264cba27435SMark Jansen
265cba27435SMark Jansen /* First entry is replaced */
266cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FOURTH_ENTRY");
267cba27435SMark Jansen ok_hex(hr, S_OK);
268cba27435SMark Jansen verify_mru(CustomMRU, L"acb", L"FOURTH_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
269cba27435SMark Jansen
270cba27435SMark Jansen CustomMRU.Release();
271cba27435SMark Jansen
272cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
273cba27435SMark Jansen ok_hex(hr, S_OK);
274cba27435SMark Jansen if (!SUCCEEDED(hr))
275cba27435SMark Jansen return;
276cba27435SMark Jansen
277cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
278cba27435SMark Jansen ok_hex(hr, S_OK);
279cba27435SMark Jansen
280cba27435SMark Jansen /* Second entry is replaced */
281cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FIFTH_ENTRY");
282cba27435SMark Jansen ok_hex(hr, S_OK);
283cba27435SMark Jansen verify_mru(CustomMRU, L"bac", L"FOURTH_ENTRY", L"FIFTH_ENTRY", L"THIRD_ENTRY");
284cba27435SMark Jansen
285cba27435SMark Jansen CustomMRU.Release();
286cba27435SMark Jansen
287cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
288cba27435SMark Jansen ok_hex(hr, S_OK);
289cba27435SMark Jansen if (!SUCCEEDED(hr))
290cba27435SMark Jansen return;
291cba27435SMark Jansen
292cba27435SMark Jansen
293cba27435SMark Jansen /* Save some garbage */
294cba27435SMark Jansen CRegKey key;
295cba27435SMark Jansen key.Open(HKEY_CURRENT_USER, szTestPath);
296cba27435SMark Jansen key.SetStringValue(L"MRUList", L"b**");
297cba27435SMark Jansen key.Close();
298cba27435SMark Jansen
299cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
300cba27435SMark Jansen ok_hex(hr, S_OK);
301cba27435SMark Jansen
302cba27435SMark Jansen CustomMRU.Release();
303cba27435SMark Jansen
304cba27435SMark Jansen /* Not cleaned up */
305cba27435SMark Jansen verify_mru(CustomMRU, L"b**", L"FOURTH_ENTRY", L"FIFTH_ENTRY", L"THIRD_ENTRY");
306cba27435SMark Jansen
307cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
308cba27435SMark Jansen ok_hex(hr, S_OK);
309cba27435SMark Jansen if (!SUCCEEDED(hr))
310cba27435SMark Jansen return;
311cba27435SMark Jansen
312cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
313cba27435SMark Jansen ok_hex(hr, S_OK);
314cba27435SMark Jansen
315cba27435SMark Jansen /* Now it's just cleaned up */
316cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"SIXTH_ENTRY");
317cba27435SMark Jansen ok_hex(hr, S_OK);
318cba27435SMark Jansen verify_mru(CustomMRU, L"ab", L"SIXTH_ENTRY");
319cba27435SMark Jansen
320cba27435SMark Jansen CustomMRU.Release();
321cba27435SMark Jansen
322cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
323cba27435SMark Jansen ok_hex(hr, S_OK);
324cba27435SMark Jansen if (!SUCCEEDED(hr))
325cba27435SMark Jansen return;
326cba27435SMark Jansen
327cba27435SMark Jansen Cleanup_Testdata();
328cba27435SMark Jansen FillDefault(CustomMRU);
329cba27435SMark Jansen verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
330cba27435SMark Jansen
331cba27435SMark Jansen CustomMRU.Release();
332cba27435SMark Jansen
333cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
334cba27435SMark Jansen ok_hex(hr, S_OK);
335cba27435SMark Jansen if (!SUCCEEDED(hr))
336cba27435SMark Jansen return;
337cba27435SMark Jansen
338cba27435SMark Jansen key.Open(HKEY_CURRENT_USER, szTestPath);
339cba27435SMark Jansen key.SetStringValue(L"MRUList", L"baccccc");
340cba27435SMark Jansen key.Close();
341cba27435SMark Jansen
342cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
343cba27435SMark Jansen ok_hex(hr, S_OK);
344cba27435SMark Jansen CustomMRU.Release();
345cba27435SMark Jansen
346cba27435SMark Jansen verify_mru(CustomMRU, L"baccccc", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
347cba27435SMark Jansen
348cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
349cba27435SMark Jansen ok_hex(hr, S_OK);
350cba27435SMark Jansen if (!SUCCEEDED(hr))
351cba27435SMark Jansen return;
352cba27435SMark Jansen
353cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
354cba27435SMark Jansen ok_hex(hr, S_OK);
355cba27435SMark Jansen
356cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FOURTH_ENTRY");
357cba27435SMark Jansen ok_hex(hr, S_OK);
358cba27435SMark Jansen verify_mru(CustomMRU, L"a", L"FOURTH_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY");
359cba27435SMark Jansen
360cba27435SMark Jansen CustomMRU.Release();
361cba27435SMark Jansen Cleanup_Testdata();
362cba27435SMark Jansen
363cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
364cba27435SMark Jansen ok_hex(hr, S_OK);
365cba27435SMark Jansen if (!SUCCEEDED(hr))
366cba27435SMark Jansen return;
367cba27435SMark Jansen
368cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
369cba27435SMark Jansen ok_hex(hr, S_OK);
370cba27435SMark Jansen if (!SUCCEEDED(hr))
371cba27435SMark Jansen return;
372cba27435SMark Jansen
373cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"FIRST_ENTRY");
374cba27435SMark Jansen ok_hex(hr, S_OK);
375cba27435SMark Jansen verify_mru(CustomMRU, L"a", L"FIRST_ENTRY");
376cba27435SMark Jansen
377cba27435SMark Jansen CustomMRU.Release();
378cba27435SMark Jansen
379cba27435SMark Jansen key.Open(HKEY_CURRENT_USER, szTestPath);
380cba27435SMark Jansen key.SetStringValue(L"MRUList", L"aaa");
381cba27435SMark Jansen key.Close();
382cba27435SMark Jansen
383cba27435SMark Jansen hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
384cba27435SMark Jansen ok_hex(hr, S_OK);
385cba27435SMark Jansen if (!SUCCEEDED(hr))
386cba27435SMark Jansen return;
387cba27435SMark Jansen
388cba27435SMark Jansen hr = CustomMRU->Initialize(szTestPath, 3);
389cba27435SMark Jansen ok_hex(hr, S_OK);
390cba27435SMark Jansen if (!SUCCEEDED(hr))
391cba27435SMark Jansen return;
392cba27435SMark Jansen
393cba27435SMark Jansen hr = CustomMRU->AddMRUString(L"SECOND_ENTRY");
394cba27435SMark Jansen ok_hex(hr, S_OK);
395cba27435SMark Jansen verify_mru(CustomMRU, L"ba", L"FIRST_ENTRY", L"SECOND_ENTRY");
396cba27435SMark Jansen }
397cba27435SMark Jansen
398b1c33293SKatayama Hirofumi MZ #define TYPED_URLS_KEY L"Software\\Microsoft\\Internet Explorer\\TypedURLs"
399b1c33293SKatayama Hirofumi MZ
400b1c33293SKatayama Hirofumi MZ static void
RestoreTypedURLs(const CStringW & url1,const CStringW & url2)401b1c33293SKatayama Hirofumi MZ RestoreTypedURLs(const CStringW& url1, const CStringW& url2)
402b1c33293SKatayama Hirofumi MZ {
403b1c33293SKatayama Hirofumi MZ CRegKey key;
404b1c33293SKatayama Hirofumi MZ key.Open(HKEY_CURRENT_USER, TYPED_URLS_KEY, KEY_WRITE);
405b1c33293SKatayama Hirofumi MZ if (url1 != L"")
406b1c33293SKatayama Hirofumi MZ key.SetStringValue(L"url1", url1);
407828a65f4SKatayama Hirofumi MZ else
408828a65f4SKatayama Hirofumi MZ key.DeleteValue(L"url1");
409b1c33293SKatayama Hirofumi MZ if (url2 != L"")
410b1c33293SKatayama Hirofumi MZ key.SetStringValue(L"url2", url2);
411828a65f4SKatayama Hirofumi MZ else
412828a65f4SKatayama Hirofumi MZ key.DeleteValue(L"url2");
413b1c33293SKatayama Hirofumi MZ }
414b1c33293SKatayama Hirofumi MZ
415b1c33293SKatayama Hirofumi MZ static void
test_IACLCustomMRU_TypedURLs()416b1c33293SKatayama Hirofumi MZ test_IACLCustomMRU_TypedURLs() // TypedURLs is special case
417b1c33293SKatayama Hirofumi MZ {
418b1c33293SKatayama Hirofumi MZ CStringW url1, url2; // Save values
419b1c33293SKatayama Hirofumi MZ {
420b1c33293SKatayama Hirofumi MZ CRegKey key;
421828a65f4SKatayama Hirofumi MZ key.Create(HKEY_CURRENT_USER, TYPED_URLS_KEY);
422b1c33293SKatayama Hirofumi MZ
423b1c33293SKatayama Hirofumi MZ WCHAR Value[MAX_PATH];
424b1c33293SKatayama Hirofumi MZ ULONG cch = _countof(Value);
425b1c33293SKatayama Hirofumi MZ LSTATUS Status = key.QueryStringValue(L"url1", Value, &cch);
426b1c33293SKatayama Hirofumi MZ if (!Status)
427b1c33293SKatayama Hirofumi MZ url1 = Value;
428b1c33293SKatayama Hirofumi MZ
429b1c33293SKatayama Hirofumi MZ cch = _countof(Value);
430b1c33293SKatayama Hirofumi MZ Status = key.QueryStringValue(L"url2", Value, &cch);
431b1c33293SKatayama Hirofumi MZ if (!Status)
432b1c33293SKatayama Hirofumi MZ url2 = Value;
433b1c33293SKatayama Hirofumi MZ
434b1c33293SKatayama Hirofumi MZ // Set values
435b1c33293SKatayama Hirofumi MZ key.SetStringValue(L"url1", L"aaa");
436b1c33293SKatayama Hirofumi MZ key.SetStringValue(L"url2", L"bbb");
437b1c33293SKatayama Hirofumi MZ }
438b1c33293SKatayama Hirofumi MZ
439b1c33293SKatayama Hirofumi MZ CComPtr<IACLCustomMRU> CustomMRU;
440b1c33293SKatayama Hirofumi MZ HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL,
441b1c33293SKatayama Hirofumi MZ IID_PPV_ARG(IACLCustomMRU, &CustomMRU));
442b1c33293SKatayama Hirofumi MZ ok_hex(hr, S_OK);
443b1c33293SKatayama Hirofumi MZ if (FAILED(hr))
444b1c33293SKatayama Hirofumi MZ {
445b1c33293SKatayama Hirofumi MZ skip("IACLCustomMRU was NULL\n");
446b1c33293SKatayama Hirofumi MZ RestoreTypedURLs(url1, url2);
447b1c33293SKatayama Hirofumi MZ return;
448b1c33293SKatayama Hirofumi MZ }
449b1c33293SKatayama Hirofumi MZ
450b1c33293SKatayama Hirofumi MZ CComPtr<IACList> ACList;
451b1c33293SKatayama Hirofumi MZ hr = CustomMRU->QueryInterface(IID_PPV_ARG(IACList, &ACList));
452b1c33293SKatayama Hirofumi MZ ok_hex(hr, S_OK);
453b1c33293SKatayama Hirofumi MZ if (SUCCEEDED(hr))
454b1c33293SKatayama Hirofumi MZ {
455b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:");
456b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
457b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:\\");
458b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
459b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:\\Program Files");
460b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
461b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:\\Program Files\\");
462b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
463b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"http://");
464b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
465b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"https://");
466b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
467b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"https://google.co.jp/");
468b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
469b1c33293SKatayama Hirofumi MZ }
470b1c33293SKatayama Hirofumi MZ
471b1c33293SKatayama Hirofumi MZ hr = CustomMRU->Initialize(TYPED_URLS_KEY, 64);
472b1c33293SKatayama Hirofumi MZ ok_hex(hr, S_OK);
473b1c33293SKatayama Hirofumi MZ
474b1c33293SKatayama Hirofumi MZ if (ACList)
475b1c33293SKatayama Hirofumi MZ {
476b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:");
477b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
478b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:\\");
479b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
480b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:\\Program Files");
481b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
482b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"C:\\Program Files\\");
483b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
484b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"http://");
485b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
486b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"https://");
487b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
488b1c33293SKatayama Hirofumi MZ hr = ACList->Expand(L"https://google.co.jp/");
489b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
490b1c33293SKatayama Hirofumi MZ }
491b1c33293SKatayama Hirofumi MZ
492b1c33293SKatayama Hirofumi MZ CComPtr<IEnumString> pEnum;
493b1c33293SKatayama Hirofumi MZ hr = CustomMRU->QueryInterface(IID_PPV_ARG(IEnumString, &pEnum));
494b1c33293SKatayama Hirofumi MZ ok_hex(hr, S_OK);
495b1c33293SKatayama Hirofumi MZ if (FAILED(hr))
496b1c33293SKatayama Hirofumi MZ {
497b1c33293SKatayama Hirofumi MZ skip("IEnumString was NULL\n");
498b1c33293SKatayama Hirofumi MZ RestoreTypedURLs(url1, url2);
499b1c33293SKatayama Hirofumi MZ return;
500b1c33293SKatayama Hirofumi MZ }
501b1c33293SKatayama Hirofumi MZ
502b1c33293SKatayama Hirofumi MZ CComPtr<IEnumString> pEnumClone;
503b1c33293SKatayama Hirofumi MZ hr = pEnum->Clone(&pEnumClone);
504b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
505b1c33293SKatayama Hirofumi MZ
506b1c33293SKatayama Hirofumi MZ hr = pEnum->Skip(1);
507b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_NOTIMPL);
508b1c33293SKatayama Hirofumi MZ
509b1c33293SKatayama Hirofumi MZ #define INVALID_LPOLESTR ((LPOLESTR)(LONG_PTR)0xDEADBEEF)
510b1c33293SKatayama Hirofumi MZ LPOLESTR apsz[2] = { NULL, INVALID_LPOLESTR };
511b1c33293SKatayama Hirofumi MZ ULONG c = 0;
512b1c33293SKatayama Hirofumi MZ hr = pEnum->Next(2, apsz, &c);
513b1c33293SKatayama Hirofumi MZ ok_hex(hr, S_OK);
514b1c33293SKatayama Hirofumi MZ ok_wstri(apsz[0], L"aaa");
515b1c33293SKatayama Hirofumi MZ ok_int(c, 1);
516b1c33293SKatayama Hirofumi MZ ok(apsz[1] == INVALID_LPOLESTR, "apsz[1] was '%S'\n", apsz[1]);
517b1c33293SKatayama Hirofumi MZ CoTaskMemFree(apsz[0]);
518b1c33293SKatayama Hirofumi MZ
519b1c33293SKatayama Hirofumi MZ LPOLESTR psz = INVALID_LPOLESTR;
520b1c33293SKatayama Hirofumi MZ c = 0;
521b1c33293SKatayama Hirofumi MZ hr = pEnum->Next(0, &psz, &c);
522b1c33293SKatayama Hirofumi MZ ok_hex(hr, S_OK);
523b1c33293SKatayama Hirofumi MZ ok(psz == INVALID_LPOLESTR, "psz was '%S'\n", psz);
524b1c33293SKatayama Hirofumi MZ ok_int(c, 0);
525b1c33293SKatayama Hirofumi MZ
526b1c33293SKatayama Hirofumi MZ psz = NULL;
527b1c33293SKatayama Hirofumi MZ c = 0;
528b1c33293SKatayama Hirofumi MZ hr = pEnum->Next(1, &psz, &c);
529b1c33293SKatayama Hirofumi MZ ok_hex(hr, S_OK);
530b1c33293SKatayama Hirofumi MZ ok_wstri(psz, L"bbb");
531b1c33293SKatayama Hirofumi MZ ok_int(c, 1);
532b1c33293SKatayama Hirofumi MZ CoTaskMemFree(psz);
533b1c33293SKatayama Hirofumi MZ
534b1c33293SKatayama Hirofumi MZ hr = CustomMRU->AddMRUString(L"https://google.co.jp");
535b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_FAIL);
536b1c33293SKatayama Hirofumi MZ hr = CustomMRU->AddMRUString(L"C:");
537b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_FAIL);
538b1c33293SKatayama Hirofumi MZ hr = CustomMRU->AddMRUString(L"C:\\");
539b1c33293SKatayama Hirofumi MZ ok_hex(hr, E_FAIL);
540b1c33293SKatayama Hirofumi MZ
541b1c33293SKatayama Hirofumi MZ RestoreTypedURLs(url1, url2);
542b1c33293SKatayama Hirofumi MZ }
543b1c33293SKatayama Hirofumi MZ
START_TEST(IACLCustomMRU)544cba27435SMark Jansen START_TEST(IACLCustomMRU)
545cba27435SMark Jansen {
546cba27435SMark Jansen CCoInit init;
547*d82185f1SMark Jansen ok_hex(init.hr, S_OK);
548*d82185f1SMark Jansen if (!SUCCEEDED(init.hr))
549cba27435SMark Jansen return;
550cba27435SMark Jansen
551cba27435SMark Jansen test_IACLCustomMRU_Basics();
552cba27435SMark Jansen test_IACLCustomMRU_UpdateOrder();
553cba27435SMark Jansen test_IACLCustomMRU_ExtraChars();
554cba27435SMark Jansen test_IACLCustomMRU_Continue();
555b1c33293SKatayama Hirofumi MZ test_IACLCustomMRU_TypedURLs();
556cba27435SMark Jansen
557cba27435SMark Jansen Cleanup_Testdata();
558cba27435SMark Jansen }
559