ReactOS 0.4.15-dev-8109-gd7be748
mru.c File Reference
#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/heap.h"
#include "wine/test.h"
Include dependency graph for mru.c:

Go to the source code of this file.

Classes

struct  tagMRUINFOA
 
struct  tagMRUINFOW
 
struct  create_lazya_t
 

Macros

#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
 
#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 */
 
#define X2(f, ord)   p##f = (void*)GetProcAddress(hComctl32, (const char *)ord);
 

Typedefs

typedef struct tagMRUINFOA MRUINFOA
 
typedef struct tagMRUINFOW MRUINFOW
 

Functions

static HANDLE (WINAPI *pCreateMRUListA)(MRUINFOA *)
 
static void (WINAPI *pFreeMRUList)(HANDLE)
 
static INT (WINAPI *pAddMRUStringA)(HANDLE
 
static void init_functions (void)
 
static LSTATUS mru_RegDeleteTreeA (HKEY hKey, LPCSTR lpszSubKey)
 
static BOOL create_reg_entries (void)
 
static void delete_reg_entries (void)
 
static void check_reg_entries (const char *mrulist, const char **items)
 
static int CALLBACK cmp_mru_strA (LPCSTR data1, LPCSTR data2)
 
static void test_MRUListA (void)
 
static void test_CreateMRUListLazyA (void)
 
static void test_EnumMRUList (void)
 
static void test_FindMRUData (void)
 
static void test_AddMRUData (void)
 
static void test_CreateMRUListW (void)
 
static void test_CreateMRUListLazyW (void)
 
 START_TEST (mru)
 

Variables

static HMODULE hComctl32
 
static LPCSTR
 
static INT
 
static LPVOID
 
static DWORD
 
static LPCVOID
 
static LPINT
 
static const create_lazya_t create_lazyA []
 

Macro Definition Documentation

◆ LIST_SIZE

#define LIST_SIZE   3 /* Max entries for each mru */

Definition at line 66 of file mru.c.

◆ MRU_BINARY

#define MRU_BINARY   1

Definition at line 63 of file mru.c.

◆ MRU_CACHEWRITE

#define MRU_CACHEWRITE   2

Definition at line 64 of file mru.c.

◆ MRU_STRING

#define MRU_STRING   0 /* this one's invented */

Definition at line 62 of file mru.c.

◆ REG_TEST_BASEKEYA

#define REG_TEST_BASEKEYA   "Software\\Wine"

Definition at line 35 of file mru.c.

◆ REG_TEST_BASESUBKEYA

#define REG_TEST_BASESUBKEYA   "Test"

Definition at line 36 of file mru.c.

◆ REG_TEST_FULLKEY

#define REG_TEST_FULLKEY   REG_TEST_KEYA "\\" REG_TEST_SUBKEYA

Definition at line 39 of file mru.c.

◆ REG_TEST_KEYA

#define REG_TEST_KEYA   REG_TEST_BASEKEYA "\\" REG_TEST_BASESUBKEYA

Definition at line 37 of file mru.c.

◆ REG_TEST_SUBKEYA

#define REG_TEST_SUBKEYA   "MRUTest"

Definition at line 38 of file mru.c.

◆ X2

#define X2 (   f,
  ord 
)    p##f = (void*)GetProcAddress(hComctl32, (const char *)ord);

Typedef Documentation

◆ MRUINFOA

◆ MRUINFOW

Function Documentation

◆ check_reg_entries()

static void check_reg_entries ( const char mrulist,
const char **  items 
)
static

Definition at line 187 of file mru.c.

188{
189 char buff[128];
190 HKEY hKey = NULL;
191 DWORD type, size, ret;
192 unsigned int i;
193
195 "Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY);
196 if (!hKey) return;
197
198 type = REG_SZ;
199 size = sizeof(buff);
200 buff[0] = '\0';
201 ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
202
203 ok(!ret && buff[0], "Checking MRU: got %d from RegQueryValueExW\n", ret);
204 if(ret || !buff[0]) return;
205
206 ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
207 mrulist, buff);
208 if(strcmp(buff, mrulist)) return;
209
210 for (i = 0; i < strlen(mrulist); i++)
211 {
212 char name[2];
213 name[0] = mrulist[i];
214 name[1] = '\0';
215 type = REG_SZ;
216 size = sizeof(buff);
217 buff[0] = '\0';
219 ok(!ret && buff[0],
220 "Checking MRU item %d ('%c'): got %d from RegQueryValueExW\n",
221 i, mrulist[i], ret);
222 if(ret || !buff[0]) return;
223 ok(!strcmp(buff, items[mrulist[i]-'a']),
224 "Checking MRU item %d ('%c'): expected \"%s\", got \"%s\"\n",
225 i, mrulist[i], buff, items[mrulist[i] - 'a']);
226 }
227}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
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
#define REG_SZ
Definition: layer.c:22
#define REG_TEST_FULLKEY
Definition: mru.c:39
static TCHAR * items[]
Definition: page1.c:45
Definition: name.c:39
unsigned char * LPBYTE
Definition: typedefs.h:53
int ret
#define HKEY_CURRENT_USER
Definition: winreg.h:11

Referenced by test_MRUListA().

◆ cmp_mru_strA()

static int CALLBACK cmp_mru_strA ( LPCSTR  data1,
LPCSTR  data2 
)
static

Definition at line 229 of file mru.c.

230{
231 return lstrcmpiA(data1, data2);
232}
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4223
Definition: tftpd.h:126
Definition: tftpd.h:138

Referenced by test_MRUListA().

◆ create_reg_entries()

static BOOL create_reg_entries ( void  )
static

Definition at line 165 of file mru.c.

166{
167 HKEY hKey = NULL;
168
170 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
171 if (!hKey) return FALSE;
173 return TRUE;
174}
#define RegCloseKey(hKey)
Definition: registry.h:49
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1179
#define REG_TEST_KEYA
Definition: mru.c:37

Referenced by START_TEST().

◆ delete_reg_entries()

static void delete_reg_entries ( void  )
static

Definition at line 176 of file mru.c.

177{
178 HKEY hKey;
179
181 &hKey))
182 return;
185}
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
#define REG_TEST_BASEKEYA
Definition: mru.c:35
static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
Definition: mru.c:99
#define REG_TEST_BASESUBKEYA
Definition: mru.c:36
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041

Referenced by START_TEST().

◆ HANDLE()

static HANDLE ( WINAPI pCreateMRUListA)
static

◆ init_functions()

static void init_functions ( void  )
static

Definition at line 80 of file mru.c.

81{
82 hComctl32 = LoadLibraryA("comctl32.dll");
83
84#define X2(f, ord) p##f = (void*)GetProcAddress(hComctl32, (const char *)ord);
85 X2(CreateMRUListA, 151);
86 X2(FreeMRUList, 152);
87 X2(AddMRUStringA, 153);
88 X2(EnumMRUListA, 154);
90 X2(AddMRUData, 167);
91 X2(FindMRUData, 169);
92 X2(CreateMRUListW, 400);
93 X2(EnumMRUListW, 403);
95#undef X2
96}
INT WINAPI FindMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
INT WINAPI AddMRUStringA(HANDLE hList, LPCSTR lpszString)
INT WINAPI EnumMRUListW(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize)
HANDLE WINAPI CreateMRUListW(const MRUINFOW *infoW)
HANDLE WINAPI CreateMRUListA(const MRUINFOA *lpcml)
INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize)
void WINAPI FreeMRUList(HANDLE hMRUList)
HANDLE WINAPI CreateMRUListLazyA(const MRUINFOA *lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
INT WINAPI AddMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData)
HANDLE WINAPI CreateMRUListLazyW(const MRUINFOW *infoW, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
#define X2(f, ord)
static HMODULE hComctl32
Definition: mru.c:68

Referenced by START_TEST().

◆ INT()

static INT ( WINAPI pAddMRUStringA)
static

◆ mru_RegDeleteTreeA()

static LSTATUS mru_RegDeleteTreeA ( HKEY  hKey,
LPCSTR  lpszSubKey 
)
static

Definition at line 99 of file mru.c.

100{
101 LONG ret;
102 DWORD dwMaxSubkeyLen, dwMaxValueLen;
103 DWORD dwMaxLen, dwSize;
104 CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
105 HKEY hSubKey = hKey;
106
107 if(lpszSubKey)
108 {
109 ret = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
110 if (ret) return ret;
111 }
112
113 /* Get highest length for keys, values */
114 ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
115 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
116 if (ret) goto cleanup;
117
118 dwMaxSubkeyLen++;
119 dwMaxValueLen++;
120 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
121 if (dwMaxLen > ARRAY_SIZE(szNameBuf))
122 {
123 /* Name too big: alloc a buffer for it */
124 if (!(lpszName = heap_alloc(dwMaxLen * sizeof(CHAR))))
125 {
127 goto cleanup;
128 }
129 }
130
131
132 /* Recursively delete all the subkeys */
133 while (TRUE)
134 {
135 dwSize = dwMaxLen;
136 if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL,
137 NULL, NULL, NULL)) break;
138
139 ret = mru_RegDeleteTreeA(hSubKey, lpszName);
140 if (ret) goto cleanup;
141 }
142
143 if (lpszSubKey)
144 ret = RegDeleteKeyA(hKey, lpszSubKey);
145 else
146 while (TRUE)
147 {
148 dwSize = dwMaxLen;
149 if (RegEnumValueA(hKey, 0, lpszName, &dwSize,
150 NULL, NULL, NULL, NULL)) break;
151
152 ret = RegDeleteValueA(hKey, lpszName);
153 if (ret) goto cleanup;
154 }
155
156cleanup:
157 /* Free buffer if allocated */
158 if (lpszName != szNameBuf)
159 heap_free(lpszName);
160 if(lpszSubKey)
161 RegCloseKey(hSubKey);
162 return ret;
163}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define ARRAY_SIZE(A)
Definition: main.h:33
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LONG WINAPI RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3583
LONG WINAPI RegEnumValueA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpdwReserved, _Out_opt_ LPDWORD lpdwType, _Out_opt_ LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData)
Definition: reg.c:2668
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2419
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
#define MAX_PATH
Definition: compat.h:34
static void cleanup(void)
Definition: main.c:1335
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define KEY_READ
Definition: nt_native.h:1023
long LONG
Definition: pedump.c:60
#define max(a, b)
Definition: svc.c:63
char CHAR
Definition: xmlstorage.h:175

Referenced by delete_reg_entries(), and mru_RegDeleteTreeA().

◆ START_TEST()

START_TEST ( mru  )

Definition at line 711 of file mru.c.

712{
714 if (!create_reg_entries())
715 return;
716
718
726
728}
static void test_CreateMRUListLazyA(void)
Definition: mru.c:473
static void test_CreateMRUListW(void)
Definition: mru.c:546
static void test_FindMRUData(void)
Definition: mru.c:516
static void test_AddMRUData(void)
Definition: mru.c:531
static void test_MRUListA(void)
Definition: mru.c:234
static void test_CreateMRUListLazyW(void)
Definition: mru.c:629
static void delete_reg_entries(void)
Definition: mru.c:176
static BOOL create_reg_entries(void)
Definition: mru.c:165
static void init_functions(void)
Definition: mru.c:80
static void test_EnumMRUList(void)
Definition: mru.c:499

◆ test_AddMRUData()

static void test_AddMRUData ( void  )
static

Definition at line 531 of file mru.c.

532{
533 INT iRet;
534
535 if (!pAddMRUData)
536 {
537 win_skip("AddMRUData entry point not found\n");
538 return;
539 }
540
541 /* NULL handle */
542 iRet = pFindMRUData(NULL, NULL, 0, NULL);
543 ok(iRet == -1, "AddMRUData expected -1, got %d\n", iRet);
544}
#define win_skip
Definition: test.h:163
int32_t INT
Definition: typedefs.h:58

Referenced by START_TEST().

◆ test_CreateMRUListLazyA()

static void test_CreateMRUListLazyA ( void  )
static

Definition at line 473 of file mru.c.

474{
475 int i;
476
477 if (!pCreateMRUListLazyA || !pFreeMRUList)
478 {
479 win_skip("CreateMRUListLazyA or FreeMRUList entry points not found\n");
480 return;
481 }
482
483 for (i = 0; i < ARRAY_SIZE(create_lazyA); i++)
484 {
485 const create_lazya_t *ptr = &create_lazyA[i];
486 HANDLE hMRU;
487
488 hMRU = pCreateMRUListLazyA((MRUINFOA*)&ptr->mruA, 0, 0, 0);
489 if (ptr->ret)
490 {
491 ok(hMRU != NULL, "%d: got %p\n", i, hMRU);
492 pFreeMRUList(hMRU);
493 }
494 else
495 ok(hMRU == NULL, "%d: got %p\n", i, hMRU);
496 }
497}
static PVOID ptr
Definition: dispmode.c:27
static const create_lazya_t create_lazyA[]
Definition: mru.c:461

Referenced by START_TEST().

◆ test_CreateMRUListLazyW()

static void test_CreateMRUListLazyW ( void  )
static

Definition at line 629 of file mru.c.

630{
631 static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0};
633 void *named;
634 HKEY hKey;
635 HANDLE hMru;
636
637 if (!pCreateMRUListLazyW)
638 {
639 win_skip("CreateMRUListLazyW entry point not found\n");
640 return;
641 }
642
643 /* check that it's not exported by name */
644 named = GetProcAddress(hComctl32, "CreateMRUListLazyW");
645 ok(named == NULL, "got %p\n", named);
646
648 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
649
650 infoW.cbSize = sizeof(infoW);
651 infoW.uMax = 1;
652 infoW.fFlags = 0;
653 infoW.lpszSubKey = mrutestW;
654 infoW.hKey = hKey;
655 infoW.lpfnCompare = NULL;
656
657 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
658 ok(hMru != NULL, "got %p\n", hMru);
659 pFreeMRUList(hMru);
660
661 /* smaller size */
662 infoW.cbSize = sizeof(infoW) - 1;
663 infoW.uMax = 1;
664 infoW.fFlags = 0;
665 infoW.lpszSubKey = mrutestW;
666 infoW.hKey = hKey;
667 infoW.lpfnCompare = NULL;
668
669 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
670 ok(hMru != NULL, "got %p\n", hMru);
671 pFreeMRUList(hMru);
672
673 /* increased size */
674 infoW.cbSize = sizeof(infoW) + 1;
675 infoW.uMax = 1;
676 infoW.fFlags = 0;
677 infoW.lpszSubKey = mrutestW;
678 infoW.hKey = hKey;
679 infoW.lpfnCompare = NULL;
680
681 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
682 ok(hMru != NULL, "got %p\n", hMru);
683 pFreeMRUList(hMru);
684
685 /* zero size */
686 infoW.cbSize = 0;
687 infoW.uMax = 1;
688 infoW.fFlags = 0;
689 infoW.lpszSubKey = mrutestW;
690 infoW.hKey = hKey;
691 infoW.lpfnCompare = NULL;
692
693 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
694 ok(hMru != NULL, "got %p\n", hMru);
695 pFreeMRUList(hMru);
696
697 /* NULL hKey */
698 infoW.cbSize = sizeof(infoW);
699 infoW.uMax = 1;
700 infoW.fFlags = 0;
701 infoW.lpszSubKey = mrutestW;
702 infoW.hKey = NULL;
703 infoW.lpfnCompare = NULL;
704
705 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
706 ok(hMru == NULL, "got %p\n", hMru);
707
709}
#define GetProcAddress(x, y)
Definition: compat.h:753
static const SecPkgInfoW infoW
Definition: kerberos.c:293
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ test_CreateMRUListW()

static void test_CreateMRUListW ( void  )
static

Definition at line 546 of file mru.c.

547{
548 static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0};
550 void *named;
551 HKEY hKey;
552 HANDLE hMru;
553
554 if (!pCreateMRUListW)
555 {
556 win_skip("CreateMRUListW entry point not found\n");
557 return;
558 }
559
560 /* exported by name too on recent versions */
561 named = GetProcAddress(hComctl32, "CreateMRUListW");
562 if (named)
563 ok(named == pCreateMRUListW, "got %p, expected %p\n", named, pCreateMRUListW);
564
566 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
567
568 infoW.cbSize = sizeof(infoW);
569 infoW.uMax = 1;
570 infoW.fFlags = 0;
571 infoW.lpszSubKey = mrutestW;
572 infoW.hKey = hKey;
573 infoW.lpfnCompare = NULL;
574
575 hMru = pCreateMRUListW(&infoW);
576 ok(hMru != NULL, "got %p\n", hMru);
577 pFreeMRUList(hMru);
578
579 /* smaller size */
580 infoW.cbSize = sizeof(infoW) - 1;
581 infoW.uMax = 1;
582 infoW.fFlags = 0;
583 infoW.lpszSubKey = mrutestW;
584 infoW.hKey = hKey;
585 infoW.lpfnCompare = NULL;
586
587 hMru = pCreateMRUListW(&infoW);
588 ok(hMru != NULL, "got %p\n", hMru);
589 pFreeMRUList(hMru);
590
591 /* increased size */
592 infoW.cbSize = sizeof(infoW) + 1;
593 infoW.uMax = 1;
594 infoW.fFlags = 0;
595 infoW.lpszSubKey = mrutestW;
596 infoW.hKey = hKey;
597 infoW.lpfnCompare = NULL;
598
599 hMru = pCreateMRUListW(&infoW);
600 ok(hMru != NULL, "got %p\n", hMru);
601 pFreeMRUList(hMru);
602
603 /* zero size */
604 infoW.cbSize = 0;
605 infoW.uMax = 1;
606 infoW.fFlags = 0;
607 infoW.lpszSubKey = mrutestW;
608 infoW.hKey = hKey;
609 infoW.lpfnCompare = NULL;
610
611 hMru = pCreateMRUListW(&infoW);
612 ok(hMru != NULL, "got %p\n", hMru);
613 pFreeMRUList(hMru);
614
615 /* NULL hKey */
616 infoW.cbSize = sizeof(infoW);
617 infoW.uMax = 1;
618 infoW.fFlags = 0;
619 infoW.lpszSubKey = mrutestW;
620 infoW.hKey = NULL;
621 infoW.lpfnCompare = NULL;
622
623 hMru = pCreateMRUListW(&infoW);
624 ok(hMru == NULL, "got %p\n", hMru);
625
627}

Referenced by START_TEST().

◆ test_EnumMRUList()

static void test_EnumMRUList ( void  )
static

Definition at line 499 of file mru.c.

500{
501 if (!pEnumMRUListA || !pEnumMRUListW)
502 {
503 win_skip("EnumMRUListA/EnumMRUListW entry point not found\n");
504 return;
505 }
506
507 /* NULL handle */
508 if (0)
509 {
510 /* crashes on NT4, passed on Win2k, XP, 2k3, Vista, 2k8 */
511 pEnumMRUListA(NULL, 0, NULL, 0);
512 pEnumMRUListW(NULL, 0, NULL, 0);
513 }
514}

Referenced by START_TEST().

◆ test_FindMRUData()

static void test_FindMRUData ( void  )
static

Definition at line 516 of file mru.c.

517{
518 INT iRet;
519
520 if (!pFindMRUData)
521 {
522 win_skip("FindMRUData entry point not found\n");
523 return;
524 }
525
526 /* NULL handle */
527 iRet = pFindMRUData(NULL, NULL, 0, NULL);
528 ok(iRet == -1, "FindMRUData expected -1, got %d\n", iRet);
529}

Referenced by START_TEST().

◆ test_MRUListA()

static void test_MRUListA ( void  )
static

Definition at line 234 of file mru.c.

235{
236 const char *checks[LIST_SIZE+1];
238 HANDLE hMRU;
239 HKEY hKey;
240 INT iRet;
241
242 if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA || !pEnumMRUListA)
243 {
244 win_skip("MRU entry points not found\n");
245 return;
246 }
247
248 if (0)
249 {
250 /* Create (NULL) - crashes native */
251 hMRU = pCreateMRUListA(NULL);
252 }
253
254 /* size too small */
255 infoA.cbSize = sizeof(infoA) - 2;
256 infoA.uMax = LIST_SIZE;
257 infoA.fFlags = MRU_STRING;
258 infoA.hKey = NULL;
259 infoA.lpszSubKey = REG_TEST_SUBKEYA;
260 infoA.lpfnCompare = cmp_mru_strA;
261
262 SetLastError(0);
263 hMRU = pCreateMRUListA(&infoA);
264 ok (!hMRU && !GetLastError(),
265 "CreateMRUListA(too small) expected NULL,0 got %p,%d\n",
266 hMRU, GetLastError());
267
268 /* size too big */
269 infoA.cbSize = sizeof(infoA) + 2;
270 infoA.uMax = LIST_SIZE;
271 infoA.fFlags = MRU_STRING;
272 infoA.hKey = NULL;
273 infoA.lpszSubKey = REG_TEST_SUBKEYA;
274 infoA.lpfnCompare = cmp_mru_strA;
275
276 SetLastError(0);
277 hMRU = pCreateMRUListA(&infoA);
278 ok (!hMRU && !GetLastError(),
279 "CreateMRUListA(too big) expected NULL,0 got %p,%d\n",
280 hMRU, GetLastError());
281
282 /* NULL hKey */
283 infoA.cbSize = sizeof(infoA);
284 infoA.uMax = LIST_SIZE;
285 infoA.fFlags = MRU_STRING;
286 infoA.hKey = NULL;
287 infoA.lpszSubKey = REG_TEST_SUBKEYA;
288 infoA.lpfnCompare = cmp_mru_strA;
289
290 SetLastError(0);
291 hMRU = pCreateMRUListA(&infoA);
292 ok (!hMRU && !GetLastError(),
293 "CreateMRUListA(NULL key) expected NULL,0 got %p,%d\n",
294 hMRU, GetLastError());
295
296 /* NULL subkey name */
297 infoA.cbSize = sizeof(infoA);
298 infoA.uMax = LIST_SIZE;
299 infoA.fFlags = MRU_STRING;
300 infoA.hKey = NULL;
301 infoA.lpszSubKey = NULL;
302 infoA.lpfnCompare = cmp_mru_strA;
303
304 SetLastError(0);
305 hMRU = pCreateMRUListA(&infoA);
306 ok (!hMRU && !GetLastError(),
307 "CreateMRUListA(NULL name) expected NULL,0 got %p,%d\n",
308 hMRU, GetLastError());
309
310 /* Create a string MRU */
312 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
313 if (!hKey) return;
314
315 infoA.cbSize = sizeof(infoA);
316 infoA.uMax = LIST_SIZE;
317 infoA.fFlags = MRU_STRING;
318 infoA.hKey = hKey;
319 infoA.lpszSubKey = REG_TEST_SUBKEYA;
320 infoA.lpfnCompare = cmp_mru_strA;
321
322 hMRU = pCreateMRUListA(&infoA);
323 ok(hMRU && !GetLastError(),
324 "CreateMRUListA(string) expected non-NULL,0 got %p,%d\n",
325 hMRU, GetLastError());
326
327 if (hMRU)
328 {
329 char buffer[255];
330 checks[0] = "Test 1";
331 checks[1] = "Test 2";
332 checks[2] = "Test 3";
333 checks[3] = "Test 4";
334
335 /* Add (NULL list) */
336 SetLastError(0);
337 iRet = pAddMRUStringA(NULL, checks[0]);
338 ok(iRet == -1 && !GetLastError(),
339 "AddMRUStringA(NULL list) expected -1,0 got %d,%d\n",
340 iRet, GetLastError());
341
342 /* Add (NULL string) */
343 if (0)
344 {
345 /* Some native versions crash when passed NULL or fail to SetLastError() */
346 SetLastError(0);
347 iRet = pAddMRUStringA(hMRU, NULL);
348 ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
349 "AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%d\n",
350 iRet, GetLastError());
351 }
352
353 /* Add 3 strings. Check the registry is correct after each add */
354 SetLastError(0);
355 iRet = pAddMRUStringA(hMRU, checks[0]);
356 ok(iRet == 0 && !GetLastError(),
357 "AddMRUStringA(1) expected 0,0 got %d,%d\n",
358 iRet, GetLastError());
359 check_reg_entries("a", checks);
360
361 SetLastError(0);
362 iRet = pAddMRUStringA(hMRU, checks[1]);
363 ok(iRet == 1 && !GetLastError(),
364 "AddMRUStringA(2) expected 1,0 got %d,%d\n",
365 iRet, GetLastError());
366 check_reg_entries("ba", checks);
367
368 SetLastError(0);
369 iRet = pAddMRUStringA(hMRU, checks[2]);
370 ok(iRet == 2 && !GetLastError(),
371 "AddMRUStringA(2) expected 2,0 got %d,%d\n",
372 iRet, GetLastError());
373 check_reg_entries("cba", checks);
374
375 /* Add a duplicate of the 2nd string - it should move to the front,
376 * but keep the same index in the registry.
377 */
378 SetLastError(0);
379 iRet = pAddMRUStringA(hMRU, checks[1]);
380 ok(iRet == 1 && !GetLastError(),
381 "AddMRUStringA(re-add 1) expected 1,0 got %d,%d\n",
382 iRet, GetLastError());
383 check_reg_entries("bca", checks);
384
385 /* Add a new string - replaces the oldest string + moves to the front */
386 SetLastError(0);
387 iRet = pAddMRUStringA(hMRU, checks[3]);
388 ok(iRet == 0 && !GetLastError(),
389 "AddMRUStringA(add new) expected 0,0 got %d,%d\n",
390 iRet, GetLastError());
391 checks[0] = checks[3];
392 check_reg_entries("abc", checks);
393
394 /* NULL buffer = get list size */
395 iRet = pEnumMRUListA(hMRU, 0, NULL, 0);
396 ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
397
398 /* negative item pos = get list size */
399 iRet = pEnumMRUListA(hMRU, -1, NULL, 0);
400 ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
401
402 /* negative item pos = get list size */
403 iRet = pEnumMRUListA(hMRU, -5, NULL, 0);
404 ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
405
406 /* negative item pos = get list size */
407 iRet = pEnumMRUListA(hMRU, -1, buffer, 255);
408 ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet);
409
410 /* negative item pos = get list size */
411 iRet = pEnumMRUListA(hMRU, -5, buffer, 255);
412 ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet);
413
414 /* check entry 0 */
415 buffer[0] = 0;
416 iRet = pEnumMRUListA(hMRU, 0, buffer, 255);
417 ok(iRet == lstrlenA(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[3]), iRet);
418 ok(strcmp(buffer, checks[3]) == 0, "EnumMRUList expected %s, got %s\n", checks[3], buffer);
419
420 /* check entry 0 with a too small buffer */
421 buffer[0] = 0; /* overwritten with 'T' */
422 buffer[1] = 'A'; /* overwritten with 0 */
423 buffer[2] = 'A'; /* unchanged */
424 buffer[3] = 0; /* unchanged */
425 iRet = pEnumMRUListA(hMRU, 0, buffer, 2);
426 ok(iRet == lstrlenA(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[3]), iRet);
427 ok(strcmp(buffer, "T") == 0, "EnumMRUList expected %s, got %s\n", "T", buffer);
428 /* make sure space after buffer has old values */
429 ok(buffer[2] == 'A', "EnumMRUList expected %02x, got %02x\n", 'A', buffer[2]);
430
431 /* check entry 1 */
432 buffer[0] = 0;
433 iRet = pEnumMRUListA(hMRU, 1, buffer, 255);
434 ok(iRet == lstrlenA(checks[1]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[1]), iRet);
435 ok(strcmp(buffer, checks[1]) == 0, "EnumMRUList expected %s, got %s\n", checks[1], buffer);
436
437 /* check entry 2 */
438 buffer[0] = 0;
439 iRet = pEnumMRUListA(hMRU, 2, buffer, 255);
440 ok(iRet == lstrlenA(checks[2]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[2]), iRet);
441 ok(strcmp(buffer, checks[2]) == 0, "EnumMRUList expected %s, got %s\n", checks[2], buffer);
442
443 /* check out of bounds entry 3 */
444 strcpy(buffer, "dummy");
445 iRet = pEnumMRUListA(hMRU, 3, buffer, 255);
446 ok(iRet == -1, "EnumMRUList expected %d, got %d\n", -1, iRet);
447 ok(strcmp(buffer, "dummy") == 0, "EnumMRUList expected unchanged buffer %s, got %s\n", "dummy", buffer);
448
449 /* Finished with this MRU */
450 pFreeMRUList(hMRU);
451 }
452
453 /* FreeMRUList(NULL) crashes on Win98 OSR0 */
454}
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
GLuint buffer
Definition: glext.h:5915
static const SecPkgInfoA infoA
Definition: kerberos.c:302
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define LIST_SIZE
Definition: mru.c:66
static void check_reg_entries(const char *mrulist, const char **items)
Definition: mru.c:187
#define REG_TEST_SUBKEYA
Definition: mru.c:38
#define MRU_STRING
Definition: mru.c:62
static int CALLBACK cmp_mru_strA(LPCSTR data1, LPCSTR data2)
Definition: mru.c:229
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by START_TEST().

◆ void()

static void ( WINAPI pFreeMRUList)
static

Variable Documentation

◆ create_lazyA

const create_lazya_t create_lazyA[]
static
Initial value:
= {
{{ 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 }
}
struct tagMRUINFOA MRUINFOA

Definition at line 461 of file mru.c.

Referenced by test_CreateMRUListLazyA().

◆ DWORD

Definition at line 72 of file mru.c.

◆ hComctl32

HMODULE hComctl32
static

Definition at line 68 of file mru.c.

Referenced by init_functions(), test_CreateMRUListLazyW(), and test_CreateMRUListW().

◆ INT

INT

Definition at line 72 of file mru.c.

◆ LPCSTR

Definition at line 71 of file mru.c.

◆ LPCVOID

Definition at line 76 of file mru.c.

◆ LPINT

Definition at line 76 of file mru.c.

◆ LPVOID

Definition at line 72 of file mru.c.