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