blob: 5b5f98ede3935597fef59d1d94880583ac9dd0e6 [file] [log] [blame]
/*
* comctl32 MRU unit tests
*
* Copyright (C) 2004 Jon Griffiths <jon_p_griffiths@yahoo.com>
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "commctrl.h"
#include "shlwapi.h"
#include "wine/test.h"
/* Keys for testing MRU functions */
#define REG_TEST_BASEKEYA "Software\\Wine"
#define REG_TEST_BASESUBKEYA "Test"
#define REG_TEST_KEYA REG_TEST_BASEKEYA "\\" REG_TEST_BASESUBKEYA
#define REG_TEST_SUBKEYA "MRUTest"
#define REG_TEST_FULLKEY REG_TEST_KEYA "\\" REG_TEST_SUBKEYA
/* Undocumented MRU functions */
typedef struct tagMRUINFOA
{
DWORD cbSize;
UINT uMax;
UINT fFlags;
HKEY hKey;
LPCSTR lpszSubKey;
int (CALLBACK *lpfnCompare)(LPCSTR, LPCSTR);
} MRUINFOA;
typedef struct tagMRUINFOW
{
DWORD cbSize;
UINT uMax;
UINT fFlags;
HKEY hKey;
LPCWSTR lpszSubKey;
int (CALLBACK *lpfnCompare)(LPCWSTR, LPCWSTR);
} MRUINFOW;
#define MRU_STRING 0 /* this one's invented */
#define MRU_BINARY 1
#define MRU_CACHEWRITE 2
#define LIST_SIZE 3 /* Max entries for each mru */
static HMODULE hComctl32;
static HANDLE (WINAPI *pCreateMRUListA)(MRUINFOA*);
static void (WINAPI *pFreeMRUList)(HANDLE);
static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR);
static INT (WINAPI *pEnumMRUListA)(HANDLE,INT,LPVOID,DWORD);
static INT (WINAPI *pEnumMRUListW)(HANDLE,INT,LPVOID,DWORD);
static HANDLE (WINAPI *pCreateMRUListLazyA)(MRUINFOA*, DWORD, DWORD, DWORD);
static HANDLE (WINAPI *pCreateMRUListLazyW)(MRUINFOW*, DWORD, DWORD, DWORD);
static INT (WINAPI *pFindMRUData)(HANDLE, LPCVOID, DWORD, LPINT);
static INT (WINAPI *pAddMRUData)(HANDLE, LPCVOID, DWORD);
static HANDLE (WINAPI *pCreateMRUListW)(MRUINFOW*);
static void InitPointers(void)
{
pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151);
pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152);
pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153);
pEnumMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)154);
pCreateMRUListLazyA = (void*)GetProcAddress(hComctl32,(LPCSTR)157);
pAddMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)167);
pFindMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)169);
pCreateMRUListW = (void*)GetProcAddress(hComctl32,(LPCSTR)400);
pEnumMRUListW = (void*)GetProcAddress(hComctl32,(LPCSTR)403);
pCreateMRUListLazyW = (void*)GetProcAddress(hComctl32,(LPCSTR)404);
}
/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */
static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
{
LONG ret;
DWORD dwMaxSubkeyLen, dwMaxValueLen;
DWORD dwMaxLen, dwSize;
CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
HKEY hSubKey = hKey;
if(lpszSubKey)
{
ret = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
if (ret) return ret;
}
/* Get highest length for keys, values */
ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
&dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
if (ret) goto cleanup;
dwMaxSubkeyLen++;
dwMaxValueLen++;
dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR))
{
/* Name too big: alloc a buffer for it */
if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(CHAR))))
{
ret = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
}
/* Recursively delete all the subkeys */
while (TRUE)
{
dwSize = dwMaxLen;
if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL,
NULL, NULL, NULL)) break;
ret = mru_RegDeleteTreeA(hSubKey, lpszName);
if (ret) goto cleanup;
}
if (lpszSubKey)
ret = RegDeleteKeyA(hKey, lpszSubKey);
else
while (TRUE)
{
dwSize = dwMaxLen;
if (RegEnumValueA(hKey, 0, lpszName, &dwSize,
NULL, NULL, NULL, NULL)) break;
ret = RegDeleteValueA(hKey, lpszName);
if (ret) goto cleanup;
}
cleanup:
/* Free buffer if allocated */
if (lpszName != szNameBuf)
HeapFree( GetProcessHeap(), 0, lpszName);
if(lpszSubKey)
RegCloseKey(hSubKey);
return ret;
}
static BOOL create_reg_entries(void)
{
HKEY hKey = NULL;
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
if (!hKey) return FALSE;
RegCloseKey(hKey);
return TRUE;
}
static void delete_reg_entries(void)
{
HKEY hKey;
if (RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_BASEKEYA, 0, KEY_ALL_ACCESS,
&hKey))
return;
mru_RegDeleteTreeA(hKey, REG_TEST_BASESUBKEYA);
RegCloseKey(hKey);
}
static void check_reg_entries(const char *mrulist, const char**items)
{
char buff[128];
HKEY hKey = NULL;
DWORD type, size, ret;
unsigned int i;
ok(!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
"Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY);
if (!hKey) return;
type = REG_SZ;
size = sizeof(buff);
buff[0] = '\0';
ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
ok(!ret && buff[0], "Checking MRU: got %d from RegQueryValueExW\n", ret);
if(ret || !buff[0]) return;
ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
mrulist, buff);
if(strcmp(buff, mrulist)) return;
for (i = 0; i < strlen(mrulist); i++)
{
char name[2];
name[0] = mrulist[i];
name[1] = '\0';
type = REG_SZ;
size = sizeof(buff);
buff[0] = '\0';
ret = RegQueryValueExA(hKey, name, NULL, &type, (LPBYTE)buff, &size);
ok(!ret && buff[0],
"Checking MRU item %d ('%c'): got %d from RegQueryValueExW\n",
i, mrulist[i], ret);
if(ret || !buff[0]) return;
ok(!strcmp(buff, items[mrulist[i]-'a']),
"Checking MRU item %d ('%c'): expected \"%s\", got \"%s\"\n",
i, mrulist[i], buff, items[mrulist[i] - 'a']);
}
}
static int CALLBACK cmp_mru_strA(LPCSTR data1, LPCSTR data2)
{
return lstrcmpiA(data1, data2);
}
static void test_MRUListA(void)
{
const char *checks[LIST_SIZE+1];
MRUINFOA infoA;
HANDLE hMRU;
HKEY hKey;
INT iRet;
if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA || !pEnumMRUListA)
{
skip("MRU entry points not found\n");
return;
}
if (0)
{
/* Create (NULL) - crashes native */
hMRU = pCreateMRUListA(NULL);
}
/* size too small */
infoA.cbSize = sizeof(infoA) - 2;
infoA.uMax = LIST_SIZE;
infoA.fFlags = MRU_STRING;
infoA.hKey = NULL;
infoA.lpszSubKey = REG_TEST_SUBKEYA;
infoA.lpfnCompare = cmp_mru_strA;
SetLastError(0);
hMRU = pCreateMRUListA(&infoA);
ok (!hMRU && !GetLastError(),
"CreateMRUListA(too small) expected NULL,0 got %p,%d\n",
hMRU, GetLastError());
/* size too big */
infoA.cbSize = sizeof(infoA) + 2;
infoA.uMax = LIST_SIZE;
infoA.fFlags = MRU_STRING;
infoA.hKey = NULL;
infoA.lpszSubKey = REG_TEST_SUBKEYA;
infoA.lpfnCompare = cmp_mru_strA;
SetLastError(0);
hMRU = pCreateMRUListA(&infoA);
ok (!hMRU && !GetLastError(),
"CreateMRUListA(too big) expected NULL,0 got %p,%d\n",
hMRU, GetLastError());
/* NULL hKey */
infoA.cbSize = sizeof(infoA);
infoA.uMax = LIST_SIZE;
infoA.fFlags = MRU_STRING;
infoA.hKey = NULL;
infoA.lpszSubKey = REG_TEST_SUBKEYA;
infoA.lpfnCompare = cmp_mru_strA;
SetLastError(0);
hMRU = pCreateMRUListA(&infoA);
ok (!hMRU && !GetLastError(),
"CreateMRUListA(NULL key) expected NULL,0 got %p,%d\n",
hMRU, GetLastError());
/* NULL subkey name */
infoA.cbSize = sizeof(infoA);
infoA.uMax = LIST_SIZE;
infoA.fFlags = MRU_STRING;
infoA.hKey = NULL;
infoA.lpszSubKey = NULL;
infoA.lpfnCompare = cmp_mru_strA;
SetLastError(0);
hMRU = pCreateMRUListA(&infoA);
ok (!hMRU && !GetLastError(),
"CreateMRUListA(NULL name) expected NULL,0 got %p,%d\n",
hMRU, GetLastError());
/* Create a string MRU */
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
if (!hKey) return;
infoA.cbSize = sizeof(infoA);
infoA.uMax = LIST_SIZE;
infoA.fFlags = MRU_STRING;
infoA.hKey = hKey;
infoA.lpszSubKey = REG_TEST_SUBKEYA;
infoA.lpfnCompare = cmp_mru_strA;
hMRU = pCreateMRUListA(&infoA);
ok(hMRU && !GetLastError(),
"CreateMRUListA(string) expected non-NULL,0 got %p,%d\n",
hMRU, GetLastError());
if (hMRU)
{
char buffer[255];
checks[0] = "Test 1";
checks[1] = "Test 2";
checks[2] = "Test 3";
checks[3] = "Test 4";
/* Add (NULL list) */
SetLastError(0);
iRet = pAddMRUStringA(NULL, checks[0]);
ok(iRet == -1 && !GetLastError(),
"AddMRUStringA(NULL list) expected -1,0 got %d,%d\n",
iRet, GetLastError());
/* Add (NULL string) */
if (0)
{
/* Some native versions crash when passed NULL or fail to SetLastError() */
SetLastError(0);
iRet = pAddMRUStringA(hMRU, NULL);
ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
"AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%d\n",
iRet, GetLastError());
}
/* Add 3 strings. Check the registry is correct after each add */
SetLastError(0);
iRet = pAddMRUStringA(hMRU, checks[0]);
ok(iRet == 0 && !GetLastError(),
"AddMRUStringA(1) expected 0,0 got %d,%d\n",
iRet, GetLastError());
check_reg_entries("a", checks);
SetLastError(0);
iRet = pAddMRUStringA(hMRU, checks[1]);
ok(iRet == 1 && !GetLastError(),
"AddMRUStringA(2) expected 1,0 got %d,%d\n",
iRet, GetLastError());
check_reg_entries("ba", checks);
SetLastError(0);
iRet = pAddMRUStringA(hMRU, checks[2]);
ok(iRet == 2 && !GetLastError(),
"AddMRUStringA(2) expected 2,0 got %d,%d\n",
iRet, GetLastError());
check_reg_entries("cba", checks);
/* Add a duplicate of the 2nd string - it should move to the front,
* but keep the same index in the registry.
*/
SetLastError(0);
iRet = pAddMRUStringA(hMRU, checks[1]);
ok(iRet == 1 && !GetLastError(),
"AddMRUStringA(re-add 1) expected 1,0 got %d,%d\n",
iRet, GetLastError());
check_reg_entries("bca", checks);
/* Add a new string - replaces the oldest string + moves to the front */
SetLastError(0);
iRet = pAddMRUStringA(hMRU, checks[3]);
ok(iRet == 0 && !GetLastError(),
"AddMRUStringA(add new) expected 0,0 got %d,%d\n",
iRet, GetLastError());
checks[0] = checks[3];
check_reg_entries("abc", checks);
/* NULL buffer = get list size */
iRet = pEnumMRUListA(hMRU, 0, NULL, 0);
ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
/* negative item pos = get list size */
iRet = pEnumMRUListA(hMRU, -1, NULL, 0);
ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
/* negative item pos = get list size */
iRet = pEnumMRUListA(hMRU, -5, NULL, 0);
ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
/* negative item pos = get list size */
iRet = pEnumMRUListA(hMRU, -1, buffer, 255);
ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet);
/* negative item pos = get list size */
iRet = pEnumMRUListA(hMRU, -5, buffer, 255);
ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet);
/* check entry 0 */
buffer[0] = 0;
iRet = pEnumMRUListA(hMRU, 0, buffer, 255);
ok(iRet == lstrlenA(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[3]), iRet);
ok(strcmp(buffer, checks[3]) == 0, "EnumMRUList expected %s, got %s\n", checks[3], buffer);
/* check entry 0 with a too small buffer */
buffer[0] = 0; /* overwritten with 'T' */
buffer[1] = 'A'; /* overwritten with 0 */
buffer[2] = 'A'; /* unchanged */
buffer[3] = 0; /* unchanged */
iRet = pEnumMRUListA(hMRU, 0, buffer, 2);
ok(iRet == lstrlenA(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[3]), iRet);
ok(strcmp(buffer, "T") == 0, "EnumMRUList expected %s, got %s\n", "T", buffer);
/* make sure space after buffer has old values */
ok(buffer[2] == 'A', "EnumMRUList expected %02x, got %02x\n", 'A', buffer[2]);
/* check entry 1 */
buffer[0] = 0;
iRet = pEnumMRUListA(hMRU, 1, buffer, 255);
ok(iRet == lstrlenA(checks[1]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[1]), iRet);
ok(strcmp(buffer, checks[1]) == 0, "EnumMRUList expected %s, got %s\n", checks[1], buffer);
/* check entry 2 */
buffer[0] = 0;
iRet = pEnumMRUListA(hMRU, 2, buffer, 255);
ok(iRet == lstrlenA(checks[2]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[2]), iRet);
ok(strcmp(buffer, checks[2]) == 0, "EnumMRUList expected %s, got %s\n", checks[2], buffer);
/* check out of bounds entry 3 */
strcpy(buffer, "dummy");
iRet = pEnumMRUListA(hMRU, 3, buffer, 255);
ok(iRet == -1, "EnumMRUList expected %d, got %d\n", -1, iRet);
ok(strcmp(buffer, "dummy") == 0, "EnumMRUList expected unchanged buffer %s, got %s\n", "dummy", buffer);
/* Finished with this MRU */
pFreeMRUList(hMRU);
}
/* FreeMRUList(NULL) crashes on Win98 OSR0 */
}
typedef struct {
MRUINFOA mruA;
BOOL ret;
} create_lazya_t;
static const create_lazya_t create_lazyA[] = {
{{ sizeof(MRUINFOA) + 1, 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE },
{{ sizeof(MRUINFOA) - 1, 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE },
{{ sizeof(MRUINFOA) + 1, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE },
{{ sizeof(MRUINFOA) - 1, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE },
{{ sizeof(MRUINFOA), 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE },
{{ sizeof(MRUINFOA), 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE },
{{ sizeof(MRUINFOA), 0, 0, NULL, "WineTest", NULL }, FALSE },
{{ 0, 0, 0, NULL, "WineTest", NULL }, FALSE },
{{ 0, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE }
};
static void test_CreateMRUListLazyA(void)
{
int i;
if (!pCreateMRUListLazyA || !pFreeMRUList)
{
win_skip("CreateMRUListLazyA or FreeMRUList entry points not found\n");
return;
}
for (i = 0; i < sizeof(create_lazyA)/sizeof(create_lazya_t); i++)
{
const create_lazya_t *ptr = &create_lazyA[i];
HANDLE hMRU;
hMRU = pCreateMRUListLazyA((MRUINFOA*)&ptr->mruA, 0, 0, 0);
if (ptr->ret)
{
ok(hMRU != NULL, "%d: got %p\n", i, hMRU);
pFreeMRUList(hMRU);
}
else
ok(hMRU == NULL, "%d: got %p\n", i, hMRU);
}
}
static void test_EnumMRUList(void)
{
if (!pEnumMRUListA || !pEnumMRUListW)
{
win_skip("EnumMRUListA/EnumMRUListW entry point not found\n");
return;
}
/* NULL handle */
if (0)
{
/* crashes on NT4, passed on Win2k, XP, 2k3, Vista, 2k8 */
pEnumMRUListA(NULL, 0, NULL, 0);
pEnumMRUListW(NULL, 0, NULL, 0);
}
}
static void test_FindMRUData(void)
{
INT iRet;
if (!pFindMRUData)
{
win_skip("FindMRUData entry point not found\n");
return;
}
/* NULL handle */
iRet = pFindMRUData(NULL, NULL, 0, NULL);
ok(iRet == -1, "FindMRUData expected -1, got %d\n", iRet);
}
static void test_AddMRUData(void)
{
INT iRet;
if (!pAddMRUData)
{
win_skip("AddMRUData entry point not found\n");
return;
}
/* NULL handle */
iRet = pFindMRUData(NULL, NULL, 0, NULL);
ok(iRet == -1, "AddMRUData expected -1, got %d\n", iRet);
}
static void test_CreateMRUListW(void)
{
static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0};
MRUINFOW infoW;
void *named;
HKEY hKey;
HANDLE hMru;
if (!pCreateMRUListW)
{
win_skip("CreateMRUListW entry point not found\n");
return;
}
/* exported by name too on recent versions */
named = GetProcAddress(hComctl32, "CreateMRUListW");
if (named)
ok(named == pCreateMRUListW, "got %p, expected %p\n", named, pCreateMRUListW);
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
infoW.cbSize = sizeof(infoW);
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListW(&infoW);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* smaller size */
infoW.cbSize = sizeof(infoW) - 1;
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListW(&infoW);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* increased size */
infoW.cbSize = sizeof(infoW) + 1;
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListW(&infoW);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* zero size */
infoW.cbSize = 0;
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListW(&infoW);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* NULL hKey */
infoW.cbSize = sizeof(infoW);
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = NULL;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListW(&infoW);
ok(hMru == NULL, "got %p\n", hMru);
RegCloseKey(hKey);
}
static void test_CreateMRUListLazyW(void)
{
static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0};
MRUINFOW infoW;
void *named;
HKEY hKey;
HANDLE hMru;
if (!pCreateMRUListLazyW)
{
win_skip("CreateMRUListLazyW entry point not found\n");
return;
}
/* check that it's not exported by name */
named = GetProcAddress(hComctl32, "CreateMRUListLazyW");
ok(named == NULL, "got %p\n", named);
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
infoW.cbSize = sizeof(infoW);
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* smaller size */
infoW.cbSize = sizeof(infoW) - 1;
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* increased size */
infoW.cbSize = sizeof(infoW) + 1;
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* zero size */
infoW.cbSize = 0;
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = hKey;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
ok(hMru != NULL, "got %p\n", hMru);
pFreeMRUList(hMru);
/* NULL hKey */
infoW.cbSize = sizeof(infoW);
infoW.uMax = 1;
infoW.fFlags = 0;
infoW.lpszSubKey = mrutestW;
infoW.hKey = NULL;
infoW.lpfnCompare = NULL;
hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
ok(hMru == NULL, "got %p\n", hMru);
RegCloseKey(hKey);
}
START_TEST(mru)
{
hComctl32 = GetModuleHandleA("comctl32.dll");
delete_reg_entries();
if (!create_reg_entries())
return;
InitPointers();
test_MRUListA();
test_CreateMRUListLazyA();
test_CreateMRUListLazyW();
test_EnumMRUList();
test_FindMRUData();
test_AddMRUData();
test_CreateMRUListW();
delete_reg_entries();
}