diff --git a/rostests/winetests/advpack/advpack.c b/rostests/winetests/advpack/advpack.c
index b09a9c6158c..b90df2d4b65 100644
--- a/rostests/winetests/advpack/advpack.c
+++ b/rostests/winetests/advpack/advpack.c
@@ -35,6 +35,7 @@
#define REG_VAL_EXISTS(key, value) !RegQueryValueEx(key, value, NULL, NULL, NULL, NULL)
#define OPEN_GUID_KEY() !RegOpenKey(HKEY_LOCAL_MACHINE, GUID_KEY, &guid)
+static HMODULE hAdvPack;
static HRESULT (WINAPI *pCloseINFEngine)(HINF);
static HRESULT (WINAPI *pDelNode)(LPCSTR,DWORD);
static HRESULT (WINAPI *pGetVersionFromFile)(LPCSTR,LPDWORD,LPDWORD,BOOL);
@@ -66,7 +67,7 @@ static void get_progfiles_dir(void)
static BOOL init_function_pointers(void)
{
- HMODULE hAdvPack = LoadLibraryA("advpack.dll");
+ hAdvPack = LoadLibraryA("advpack.dll");
if (!hAdvPack)
return FALSE;
@@ -521,7 +522,7 @@ static void setperusersecvalues_test(void)
/* set initial values */
lstrcpy(peruser.szGUID, "guid");
hr = pSetPerUserSecValues(&peruser);
- ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
+ ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok(OPEN_GUID_KEY(), "Expected guid key to exist\n");
ok(check_reg_str(guid, NULL, "displayname"), "Expected displayname\n");
ok(check_reg_str(guid, "ComponentID", "compid"), "Expected compid\n");
@@ -538,7 +539,7 @@ static void setperusersecvalues_test(void)
/* raise the version, but bRollback is FALSE, so vals not saved */
lstrcpy(peruser.szVersion, "2,1,1,1");
hr = pSetPerUserSecValues(&peruser);
- ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
+ ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok(check_reg_str(guid, NULL, "displayname"), "Expected displayname\n");
ok(check_reg_str(guid, "ComponentID", "compid"), "Expected compid\n");
ok(check_reg_str(guid, "Locale", "locale"), "Expected locale\n");
@@ -555,7 +556,7 @@ static void setperusersecvalues_test(void)
peruser.bRollback = TRUE;
lstrcpy(peruser.szVersion, "3,1,1,1");
hr = pSetPerUserSecValues(&peruser);
- ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
+ ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok(check_reg_str(guid, NULL, "displayname"), "Expected displayname\n");
ok(check_reg_str(guid, "ComponentID", "compid"), "Expected compid\n");
ok(check_reg_str(guid, "Locale", "locale"), "Expected locale\n");
@@ -594,4 +595,6 @@ START_TEST(advpack)
setperusersecvalues_test();
translateinfstring_test();
translateinfstringex_test();
+
+ FreeLibrary(hAdvPack);
}
diff --git a/rostests/winetests/advpack/advpack.rbuild b/rostests/winetests/advpack/advpack.rbuild
index baabd337d90..09e93fde4d9 100644
--- a/rostests/winetests/advpack/advpack.rbuild
+++ b/rostests/winetests/advpack/advpack.rbuild
@@ -1,17 +1,18 @@
+
.
0x600
0x600
- wine
- cabinet
- user32
- advapi32
- kernel32
- ntdll
advpack.c
files.c
install.c
testlist.c
+ wine
+ cabinet
+ advapi32
+ kernel32
+ ntdll
+
diff --git a/rostests/winetests/advpack/files.c b/rostests/winetests/advpack/files.c
index 71c1741d957..e109a88aacc 100644
--- a/rostests/winetests/advpack/files.c
+++ b/rostests/winetests/advpack/files.c
@@ -560,4 +560,6 @@ START_TEST(files)
test_AdvInstallFile();
delete_test_files();
+
+ FreeLibrary(hAdvPack);
}
diff --git a/rostests/winetests/advpack/install.c b/rostests/winetests/advpack/install.c
index 607596347f5..564ecda71c9 100644
--- a/rostests/winetests/advpack/install.c
+++ b/rostests/winetests/advpack/install.c
@@ -23,6 +23,7 @@
#include
#include "wine/test.h"
+static HMODULE hAdvPack;
/* function pointers */
static HRESULT (WINAPI *pRunSetupCommand)(HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, HANDLE*, DWORD, LPVOID);
static HRESULT (WINAPI *pLaunchINFSection)(HWND, HINSTANCE, LPSTR, INT);
@@ -32,7 +33,7 @@ static char CURR_DIR[MAX_PATH];
static BOOL init_function_pointers(void)
{
- HMODULE hAdvPack = LoadLibraryA("advpack.dll");
+ hAdvPack = LoadLibraryA("advpack.dll");
if (!hAdvPack)
return FALSE;
@@ -273,4 +274,6 @@ START_TEST(install)
test_RunSetupCommand();
test_LaunchINFSection();
test_LaunchINFSectionEx();
+
+ FreeLibrary(hAdvPack);
}
diff --git a/rostests/winetests/cabinet/cabinet.rbuild b/rostests/winetests/cabinet/cabinet.rbuild
index c119392bc1a..dcac40f8af4 100644
--- a/rostests/winetests/cabinet/cabinet.rbuild
+++ b/rostests/winetests/cabinet/cabinet.rbuild
@@ -1,15 +1,16 @@
+
.
0x600
0x600
- wine
- cabinet
- user32
- kernel32
- ntdll
extract.c
fdi.c
testlist.c
+ wine
+ cabinet
+ kernel32
+ ntdll
+
diff --git a/rostests/winetests/cabinet/extract.c b/rostests/winetests/cabinet/extract.c
index 2cf5154b7af..156df177a9b 100644
--- a/rostests/winetests/cabinet/extract.c
+++ b/rostests/winetests/cabinet/extract.c
@@ -28,7 +28,7 @@
#define MEDIA_SIZE 999999999
#define FOLDER_THRESHOLD 900000
-/* The following defintions were copied from dlls/cabinet/cabinet.h
+/* The following definitions were copied from dlls/cabinet/cabinet.h
* because they are undocumented in windows.
*/
diff --git a/rostests/winetests/cabinet/fdi.c b/rostests/winetests/cabinet/fdi.c
index 7c10b3d1663..18745f26061 100644
--- a/rostests/winetests/cabinet/fdi.c
+++ b/rostests/winetests/cabinet/fdi.c
@@ -92,10 +92,6 @@ static void test_FDICreate(void)
HFDI hfdi;
ERF erf;
- erf.erfOper = 0xcafefeed;
- erf.erfType = 0xdeadbabe;
- erf.fError = 0xdecaface;
-
/* native crashes if pfnalloc is NULL */
/* FDICreate does not crash with a NULL pfnfree,
@@ -104,6 +100,9 @@ static void test_FDICreate(void)
if (0)
{
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, NULL, fdi_open, fdi_read,
fdi_write, fdi_close, fdi_seek,
cpuUNKNOWN, &erf);
@@ -118,99 +117,121 @@ static void test_FDICreate(void)
}
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, fdi_free, NULL, fdi_read,
fdi_write, fdi_close, fdi_seek,
cpuUNKNOWN, &erf);
ok(hfdi != NULL, "Expected non-NULL context\n");
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
- ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
- ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
- ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
+ ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper);
+ ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType);
+ ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError);
FDIDestroy(hfdi);
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, NULL,
fdi_write, fdi_close, fdi_seek,
cpuUNKNOWN, &erf);
ok(hfdi != NULL, "Expected non-NULL context\n");
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
- ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
- ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
- ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
+ ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper);
+ ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType);
+ ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError);
FDIDestroy(hfdi);
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
NULL, fdi_close, fdi_seek,
cpuUNKNOWN, &erf);
ok(hfdi != NULL, "Expected non-NULL context\n");
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
- ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
- ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
- ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
+ ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper);
+ ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType);
+ ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError);
FDIDestroy(hfdi);
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
fdi_write, NULL, fdi_seek,
cpuUNKNOWN, &erf);
ok(hfdi != NULL, "Expected non-NULL context\n");
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
- ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
- ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
- ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
+ ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper);
+ ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType);
+ ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError);
FDIDestroy(hfdi);
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
fdi_write, fdi_close, NULL,
cpuUNKNOWN, &erf);
ok(hfdi != NULL, "Expected non-NULL context\n");
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
- ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
- ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
- ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
+ ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper);
+ ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType);
+ ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError);
FDIDestroy(hfdi);
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
fdi_write, fdi_close, fdi_seek,
cpuUNKNOWN, NULL);
- ok(hfdi != NULL, "Expected non-NULL context\n");
+ /* XP sets hfdi to a non-NULL value, but Vista sets it to NULL! */
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
- ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
- ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
- ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
+ /* NULL is passed to FDICreate instead of &erf, so don't retest the erf member values. */
FDIDestroy(hfdi);
/* bad cpu type */
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
fdi_write, fdi_close, fdi_seek,
0xcafebabe, &erf);
ok(hfdi != NULL, "Expected non-NULL context\n");
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
- ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
- ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
- ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
+ ok((erf.erfOper == 0xcafefeed || erf.erfOper == 0 /* Vista */), "Expected 0xcafefeed or 0, got %d\n", erf.erfOper);
+ ok((erf.erfType == 0xdeadbabe || erf.erfType == 0 /* Vista */), "Expected 0xdeadbabe or 0, got %d\n", erf.erfType);
+ ok((erf.fError == 0xdecaface || erf.fError == 0 /* Vista */), "Expected 0xdecaface or 0, got %d\n", erf.fError);
FDIDestroy(hfdi);
/* pfnalloc fails */
SetLastError(0xdeadbeef);
+ erf.erfOper = 0xcafefeed;
+ erf.erfType = 0xdeadbabe;
+ erf.fError = 0xdecaface;
hfdi = FDICreate(fdi_alloc_bad, fdi_free, fdi_open, fdi_read,
fdi_write, fdi_close, fdi_seek,
cpuUNKNOWN, &erf);
diff --git a/rostests/winetests/comcat/comcat.rbuild b/rostests/winetests/comcat/comcat.rbuild
index 7fe8a38683f..dc42865a654 100644
--- a/rostests/winetests/comcat/comcat.rbuild
+++ b/rostests/winetests/comcat/comcat.rbuild
@@ -1,15 +1,17 @@
+
.
0x600
0x600
+ comcat.c
+ testlist.c
wine
ole32
advapi32
kernel32
uuid
ntdll
- comcat.c
- testlist.c
+
diff --git a/rostests/winetests/comctl32/comboex.c b/rostests/winetests/comctl32/comboex.c
index f3f46b3da36..ad58643f648 100644
--- a/rostests/winetests/comctl32/comboex.c
+++ b/rostests/winetests/comctl32/comboex.c
@@ -187,10 +187,23 @@ static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, L
return 0L;
}
-static void init(void) {
+static int init(void)
+{
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
WNDCLASSA wc;
+ INITCOMMONCONTROLSEX iccex;
- InitCommonControls();
+ hComctl32 = GetModuleHandleA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (!pInitCommonControlsEx)
+ {
+ skip("InitCommonControlsEx() is missing. Skipping the tests\n");
+ return 0;
+ }
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_USEREX_CLASSES;
+ pInitCommonControlsEx(&iccex);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
@@ -209,7 +222,7 @@ static void init(void) {
assert(hComboExParentWnd != NULL);
hMainHinst = GetModuleHandleA(NULL);
-
+ return 1;
}
static void cleanup(void)
@@ -227,7 +240,8 @@ static void cleanup(void)
START_TEST(comboex)
{
- init();
+ if (!init())
+ return;
test_comboboxex();
diff --git a/rostests/winetests/comctl32/comctl32.rbuild b/rostests/winetests/comctl32/comctl32.rbuild
index f7ed7ae4fc4..307b6dcb217 100644
--- a/rostests/winetests/comctl32/comctl32.rbuild
+++ b/rostests/winetests/comctl32/comctl32.rbuild
@@ -5,14 +5,6 @@
.
0x600
0x600
- wine
- comctl32
- ole32
- user32
- gdi32
- advapi32
- kernel32
- ntdll
comboex.c
datetime.c
dpa.c
@@ -36,5 +28,13 @@
updown.c
rsrc.rc
testlist.c
+ wine
+ comctl32
+ ole32
+ user32
+ gdi32
+ advapi32
+ kernel32
+ ntdll
diff --git a/rostests/winetests/comctl32/datetime.c b/rostests/winetests/comctl32/datetime.c
index 956f16e9db7..b194cc1b6ae 100644
--- a/rostests/winetests/comctl32/datetime.c
+++ b/rostests/winetests/comctl32/datetime.c
@@ -112,6 +112,7 @@ static const struct message test_dtm_set_range_swap_min_max_seq[] = {
static const struct message test_dtm_set_and_get_system_time_seq[] = {
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 },
+ { 0x0090, sent|optional }, /* Vista */
{ WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
{ WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 },
@@ -125,6 +126,7 @@ static const struct message test_dtm_set_and_get_system_time_seq[] = {
};
static const struct message destroy_window_seq[] = {
+ { 0x0090, sent|optional }, /* Vista */
{ WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
{ WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
{ 0 }
@@ -191,6 +193,8 @@ static HWND create_datetime_control(DWORD style, DWORD exstyle)
static void test_dtm_set_format(HWND hWndDateTime)
{
+ CHAR txt[256];
+ SYSTEMTIME systime;
LRESULT r;
r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, (LPARAM)NULL);
@@ -201,6 +205,17 @@ static void test_dtm_set_format(HWND hWndDateTime)
expect(1, r);
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_format_seq, "test_dtm_set_format", FALSE);
+
+ r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0,
+ (LPARAM)"'hh' hh");
+ expect(1, r);
+ ZeroMemory(&systime, sizeof(systime));
+ systime.wYear = 2000;
+ systime.wMonth = systime.wDay = 1;
+ r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime);
+ expect(1, r);
+ GetWindowText(hWndDateTime, txt, 256);
+ todo_wine ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
}
@@ -311,7 +326,7 @@ static void test_dtm_set_and_get_range(HWND hWndDateTime)
/* initialize st[0] to lowest possible value */
fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
- /* intialize st[1] to all invalid numbers */
+ /* initialize st[1] to all invalid numbers */
fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000);
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
@@ -560,7 +575,21 @@ static void test_datetime_control(void)
START_TEST(datetime)
{
- InitCommonControls();
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
+ INITCOMMONCONTROLSEX iccex;
+
+ hComctl32 = GetModuleHandleA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (!pInitCommonControlsEx)
+ {
+ skip("InitCommonControlsEx() is missing. Skipping the tests\n");
+ return;
+ }
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_DATE_CLASSES;
+ pInitCommonControlsEx(&iccex);
+
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
test_datetime_control();
diff --git a/rostests/winetests/comctl32/dpa.c b/rostests/winetests/comctl32/dpa.c
index f1ca8f23e25..b2ea3d8c327 100644
--- a/rostests/winetests/comctl32/dpa.c
+++ b/rostests/winetests/comctl32/dpa.c
@@ -219,7 +219,7 @@ static void test_dpa(void)
/* Set item with out of bound index */
ok(pDPA_SetPtr(dpa, 1, (PVOID)6), "\n");
- /* Fill the greated gap */
+ /* Fill the created gap */
ok(pDPA_SetPtr(dpa, 0, (PVOID)5), "\n");
rc=CheckDPA(dpa, 0x56, &dw);
ok(rc, "dw=0x%x\n", dw);
@@ -454,6 +454,4 @@ START_TEST(dpa)
test_dpa();
else
trace("skipping tests\n");
-
- FreeLibrary(hcomctl32);
}
diff --git a/rostests/winetests/comctl32/header.c b/rostests/winetests/comctl32/header.c
index fa75d49046f..6f8b46250f8 100644
--- a/rostests/winetests/comctl32/header.c
+++ b/rostests/winetests/comctl32/header.c
@@ -1156,7 +1156,7 @@ static void test_hdm_index_messages(HWND hParent)
ok_sequence(sequences, HEADER_SEQ_INDEX, orderArray_seq, "set_get_orderArray sequence testing", FALSE);
- /* check if the array order is set correctly and the size of the array is corret. */
+ /* check if the array order is set correctly and the size of the array is correct. */
expect(2, iSize);
expect(lpiarray[0], lpiarrayReceived[0]);
expect(lpiarray[1], lpiarrayReceived[1]);
@@ -1480,10 +1480,24 @@ static LRESULT CALLBACK HeaderTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LP
return 0L;
}
-static void init(void) {
+static int init(void)
+{
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
WNDCLASSA wc;
+ INITCOMMONCONTROLSEX iccex;
- InitCommonControls();
+ hComctl32 = GetModuleHandleA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (!pInitCommonControlsEx)
+ {
+ skip("InitCommonControlsEx() is missing. Skipping the tests\n");
+ return 0;
+ }
+
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_USEREX_CLASSES;
+ pInitCommonControlsEx(&iccex);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
@@ -1503,13 +1517,15 @@ static void init(void) {
NULL, NULL, GetModuleHandleA(NULL), 0);
assert(hHeaderParentWnd != NULL);
ShowWindow(hHeaderParentWnd, SW_SHOW);
+ return 1;
}
START_TEST(header)
{
HWND parent_hwnd;
- init();
+ if (!init())
+ return;
test_header_control();
test_header_order();
diff --git a/rostests/winetests/comctl32/listview.c b/rostests/winetests/comctl32/listview.c
index 30a81a8948f..ad82579af00 100644
--- a/rostests/winetests/comctl32/listview.c
+++ b/rostests/winetests/comctl32/listview.c
@@ -539,6 +539,44 @@ static void test_checkboxes(void)
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
ok(item.state == 0x1aaa, "state %x\n", item.state);
+ /* Toggle checkbox tests (bug 9934) */
+ memset (&item, 0xcc, sizeof(item));
+ item.mask = LVIF_STATE;
+ item.iItem = 3;
+ item.iSubItem = 0;
+ item.state = LVIS_FOCUSED;
+ item.stateMask = LVIS_FOCUSED;
+ r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM) &item);
+ expect(1, r);
+
+ item.iItem = 3;
+ item.mask = LVIF_STATE;
+ item.stateMask = 0xffff;
+ r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
+ ok(item.state == 0x1aab, "state %x\n", item.state);
+
+ r = SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0);
+ expect(0, r);
+ r = SendMessage(hwnd, WM_KEYUP, VK_SPACE, 0);
+ expect(0, r);
+
+ item.iItem = 3;
+ item.mask = LVIF_STATE;
+ item.stateMask = 0xffff;
+ r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
+ ok(item.state == 0x2aab, "state %x\n", item.state);
+
+ r = SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0);
+ expect(0, r);
+ r = SendMessage(hwnd, WM_KEYUP, VK_SPACE, 0);
+ expect(0, r);
+
+ item.iItem = 3;
+ item.mask = LVIF_STATE;
+ item.stateMask = 0xffff;
+ r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
+ ok(item.state == 0x1aab, "state %x\n", item.state);
+
DestroyWindow(hwnd);
}
@@ -547,7 +585,7 @@ static void insert_column(HWND hwnd, int idx)
LVCOLUMN column;
DWORD rc;
- memset(&column, 0xaa, sizeof(column));
+ memset(&column, 0xcc, sizeof(column));
column.mask = LVCF_SUBITEM;
column.iSubItem = idx;
@@ -562,7 +600,7 @@ static void insert_item(HWND hwnd, int idx)
LVITEMA item;
DWORD rc;
- memset(&item, 0xaa, sizeof (item));
+ memset(&item, 0xcc, sizeof (item));
item.mask = LVIF_TEXT;
item.iItem = idx;
item.iSubItem = 0;
@@ -593,7 +631,7 @@ static void test_items(void)
insert_column(hwnd, 1);
/* Insert an item with just a param */
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_PARAM;
item.iItem = 0;
item.iSubItem = 0;
@@ -602,7 +640,7 @@ static void test_items(void)
ok(r == 0, "ret %d\n", r);
/* Test getting of the param */
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_PARAM;
item.iItem = 0;
item.iSubItem = 0;
@@ -611,7 +649,7 @@ static void test_items(void)
ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
/* Set up a subitem */
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_TEXT;
item.iItem = 0;
item.iSubItem = 1;
@@ -620,7 +658,7 @@ static void test_items(void)
ok(r != 0, "ret %d\n", r);
/* Query param from subitem: returns main item param */
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_PARAM;
item.iItem = 0;
item.iSubItem = 1;
@@ -629,7 +667,7 @@ static void test_items(void)
ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
/* Set up param on first subitem: no effect */
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_PARAM;
item.iItem = 0;
item.iSubItem = 1;
@@ -638,7 +676,7 @@ static void test_items(void)
ok(r == 0, "ret %d\n", r);
/* Query param from subitem again: should still return main item param */
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_PARAM;
item.iItem = 0;
item.iSubItem = 1;
@@ -647,7 +685,7 @@ static void test_items(void)
ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
/**** Some tests of state highlighting ****/
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_STATE;
item.iItem = 0;
item.iSubItem = 0;
@@ -660,7 +698,7 @@ static void test_items(void)
r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM) &item);
ok(r != 0, "ret %d\n", r);
- memset (&item, 0xaa, sizeof (item));
+ memset (&item, 0xcc, sizeof (item));
item.mask = LVIF_STATE;
item.iItem = 0;
item.iSubItem = 0;
@@ -687,7 +725,7 @@ static void test_columns(void)
ok(hwnd != NULL, "failed to create listview window\n");
/* Add a column with no mask */
- memset(&column, 0xaa, sizeof(column));
+ memset(&column, 0xcc, sizeof(column));
column.mask = 0;
rc = ListView_InsertColumn(hwnd, 0, &column);
ok(rc==0, "Inserting column with no mask failed with %d\n", rc);
@@ -1040,7 +1078,20 @@ static void test_item_position(void)
START_TEST(listview)
{
- InitCommonControls();
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
+
+ hComctl32 = GetModuleHandleA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (pInitCommonControlsEx)
+ {
+ INITCOMMONCONTROLSEX iccex;
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_LISTVIEW_CLASSES;
+ pInitCommonControlsEx(&iccex);
+ }
+ else
+ InitCommonControls();
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
diff --git a/rostests/winetests/comctl32/monthcal.c b/rostests/winetests/comctl32/monthcal.c
index d670004f8ad..7f3b4e53ab6 100644
--- a/rostests/winetests/comctl32/monthcal.c
+++ b/rostests/winetests/comctl32/monthcal.c
@@ -281,6 +281,7 @@ static const struct message destroy_monthcal_parent_msgs_seq[] = {
/* expected message sequence for child*/
static const struct message destroy_monthcal_child_msgs_seq[] = {
+ { 0x0090, sent|optional }, /* Vista */
{ WM_SHOWWINDOW, sent|wparam|lparam, 0, 0},
{ WM_WINDOWPOSCHANGING, sent|wparam, 0},
{ WM_WINDOWPOSCHANGED, sent|wparam, 0},
@@ -290,6 +291,7 @@ static const struct message destroy_monthcal_child_msgs_seq[] = {
};
static const struct message destroy_monthcal_multi_sel_style_seq[] = {
+ { 0x0090, sent|optional }, /* Vista */
{ WM_DESTROY, sent|wparam|lparam, 0, 0},
{ WM_NCDESTROY, sent|wparam|lparam, 0, 0},
{ 0 }
@@ -297,6 +299,7 @@ static const struct message destroy_monthcal_multi_sel_style_seq[] = {
/* expected message sequence for parent window*/
static const struct message destroy_parent_seq[] = {
+ { 0x0090, sent|optional }, /* Vista */
{ WM_WINDOWPOSCHANGING, sent|wparam, 0},
{ WM_WINDOWPOSCHANGED, sent|wparam, 0},
{ WM_NCACTIVATE, sent|wparam|lparam, 0, 0},
@@ -316,7 +319,6 @@ static void test_monthcal(void)
SYSTEMTIME st[2], st1[2];
int res, month_range;
- InitCommonControls();
hwnd = CreateWindowA(MONTHCAL_CLASSA, "MonthCal", WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,
0, 300, 300, 0, 0, NULL, NULL);
ok(hwnd != NULL, "Failed to create MonthCal\n");
@@ -479,8 +481,6 @@ static HWND create_monthcal_control(DWORD style, HWND parent_window)
struct subclass_info *info;
HWND hwnd;
- InitCommonControls();
-
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
if (!info)
return NULL;
@@ -720,7 +720,7 @@ static void test_monthcal_unicode(HWND hwnd)
static void test_monthcal_HitTest(HWND hwnd)
{
MCHITTESTINFO mchit;
- int res;
+ UINT res;
SYSTEMTIME st;
memset(&mchit, 0, sizeof(MCHITTESTINFO));
@@ -912,7 +912,7 @@ static void test_monthcal_todaylink(HWND hwnd)
MCHITTESTINFO mchit;
SYSTEMTIME st_test, st_new;
BOOL error = FALSE;
- int res;
+ UINT res;
memset(&mchit, 0, sizeof(MCHITTESTINFO));
@@ -1110,7 +1110,22 @@ static void test_monthcal_MaxSelDay(HWND hwnd)
START_TEST(monthcal)
{
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
+ INITCOMMONCONTROLSEX iccex;
HWND hwnd, parent_wnd;
+
+ hComctl32 = GetModuleHandleA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (!pInitCommonControlsEx)
+ {
+ skip("InitCommonControlsEx() is missing. Skipping the tests\n");
+ return;
+ }
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_DATE_CLASSES;
+ pInitCommonControlsEx(&iccex);
+
test_monthcal();
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
diff --git a/rostests/winetests/comctl32/progress.c b/rostests/winetests/comctl32/progress.c
index 2716f3356b4..10bbbef8a28 100644
--- a/rostests/winetests/comctl32/progress.c
+++ b/rostests/winetests/comctl32/progress.c
@@ -90,10 +90,22 @@ static void update_window(HWND hWnd)
static void init(void)
{
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
WNDCLASSA wc;
RECT rect;
- InitCommonControls();
+ hComctl32 = GetModuleHandleA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (pInitCommonControlsEx)
+ {
+ INITCOMMONCONTROLSEX iccex;
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_PROGRESS_CLASS;
+ pInitCommonControlsEx(&iccex);
+ }
+ else
+ InitCommonControls();
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
diff --git a/rostests/winetests/comctl32/rebar.c b/rostests/winetests/comctl32/rebar.c
index 6bebeb770a4..e5bea381025 100644
--- a/rostests/winetests/comctl32/rebar.c
+++ b/rostests/winetests/comctl32/rebar.c
@@ -17,6 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+/* make sure the structures work with a comctl32 v5.x */
+#define _WIN32_WINNT 0x500
+#define _WIN32_IE 0x500
+
#include
#include
@@ -252,6 +256,21 @@ rbsize_result_t rbsize_results[] = {
{ {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
{ { 0, 20, 672, 40}, 0x00, 200},
}, },
+ { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
+ { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214},
+ { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161},
+ { { 0, 28, 672, 56}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
+ { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
+ { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
+ { { 0, 20, 672, 40}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
+ { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214},
+ { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161},
+ { { 0, 28, 672, 56}, 0x00, 200},
+ }, },
{ {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
}, },
{ {0, 0, 672, 65}, 65, 1, {65, }, 3, {
@@ -329,6 +348,8 @@ static void layout_test(void)
{
HWND hRebar = NULL;
REBARBANDINFO rbi;
+ HIMAGELIST himl;
+ REBARINFO ri;
rebuild_rebar(&hRebar);
check_sizes();
@@ -406,6 +427,27 @@ static void layout_test(void)
SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
check_sizes();
+ /* an image will increase the band height */
+ himl = ImageList_LoadImage(LoadLibrary("comctl32"), MAKEINTRESOURCE(121), 24, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
+ ri.cbSize = sizeof(ri);
+ ri.fMask = RBIM_IMAGELIST;
+ ri.himl = himl;
+ ok(SendMessage(hRebar, RB_SETBARINFO, 0, (LPARAM)&ri), "RB_SETBARINFO failed\n");
+ rbi.fMask = RBBIM_IMAGE;
+ rbi.iImage = 1;
+ SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
+ check_sizes();
+
+ /* after removing it everything is back to normal*/
+ rbi.iImage = -1;
+ SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
+ check_sizes();
+
+ /* Only -1 means that the image is not present. Other invalid values increase the height */
+ rbi.iImage = -2;
+ SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
+ check_sizes();
+
/* VARHEIGHT resizing test on a horizontal rebar */
rebuild_rebar(&hRebar);
SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
@@ -786,11 +828,24 @@ static void bandinfo_test(void)
START_TEST(rebar)
{
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
+ INITCOMMONCONTROLSEX iccex;
WNDCLASSA wc;
MSG msg;
RECT rc;
- InitCommonControls();
+ /* LoadLibrary is needed. This file has no references to functions in comctl32 */
+ hComctl32 = LoadLibraryA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (!pInitCommonControlsEx)
+ {
+ skip("InitCommonControlsEx() is missing. Skipping the tests\n");
+ return;
+ }
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_COOL_CLASSES;
+ pInitCommonControlsEx(&iccex);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
@@ -825,4 +880,6 @@ START_TEST(rebar)
DispatchMessageA(&msg);
}
DestroyWindow(hMainWnd);
+
+ FreeLibrary(hComctl32);
}
diff --git a/rostests/winetests/comctl32/toolbar.c b/rostests/winetests/comctl32/toolbar.c
index b094a4bfc0d..2693025b2e3 100644
--- a/rostests/winetests/comctl32/toolbar.c
+++ b/rostests/winetests/comctl32/toolbar.c
@@ -40,6 +40,8 @@ static BOOL g_fExpectedHotItemOld;
static BOOL g_fExpectedHotItemNew;
static DWORD g_dwExpectedDispInfoMask;
+#define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT))
+
#define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
@@ -1088,6 +1090,38 @@ static void test_setrows(void)
DestroyWindow(hToolbar);
}
+static void test_getstring(void)
+{
+ HWND hToolbar = NULL;
+ char str[10];
+ WCHAR strW[10];
+ static const char answer[] = "STR";
+ static const WCHAR answerW[] = { 'S','T','R',0 };
+ INT r;
+
+ hToolbar = CreateWindowExA(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hMainWnd, (HMENU)5, GetModuleHandle(NULL), NULL);
+ ok(hToolbar != NULL, "Toolbar creation problem\n");
+
+ r = SendMessage(hToolbar, TB_GETSTRING, MAKEWPARAM(0, 0), (LPARAM)NULL);
+ expect(-1, r);
+ r = SendMessage(hToolbar, TB_GETSTRINGW, MAKEWPARAM(0, 0), (LPARAM)NULL);
+ expect(-1, r);
+ r = SendMessage(hToolbar, TB_ADDSTRING, 0, (LPARAM)answer);
+ expect(0, r);
+ r = SendMessage(hToolbar, TB_GETSTRING, MAKEWPARAM(0, 0), (LPARAM)NULL);
+ expect(lstrlenA(answer), r);
+ r = SendMessage(hToolbar, TB_GETSTRINGW, MAKEWPARAM(0, 0), (LPARAM)NULL);
+ expect(lstrlenA(answer), r);
+ r = SendMessage(hToolbar, TB_GETSTRING, MAKEWPARAM(sizeof(str), 0), (LPARAM)str);
+ expect(lstrlenA(answer), r);
+ expect(0, lstrcmp(answer, str));
+ r = SendMessage(hToolbar, TB_GETSTRINGW, MAKEWPARAM(sizeof(strW), 0), (LPARAM)strW);
+ expect(lstrlenA(answer), r);
+ expect(0, lstrcmpW(answerW, strW));
+
+ DestroyWindow(hToolbar);
+}
+
START_TEST(toolbar)
{
WNDCLASSA wc;
@@ -1122,6 +1156,7 @@ START_TEST(toolbar)
test_createtoolbarex();
test_dispinfo();
test_setrows();
+ test_getstring();
PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) {
diff --git a/rostests/winetests/comctl32/tooltips.c b/rostests/winetests/comctl32/tooltips.c
index 713fa240368..e9bce637be8 100644
--- a/rostests/winetests/comctl32/tooltips.c
+++ b/rostests/winetests/comctl32/tooltips.c
@@ -1,5 +1,6 @@
/*
* Copyright 2005 Dmitry Timoshkov
+ * Copyright 2008 Jason Edmeades
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -60,9 +61,181 @@ static void test_create_tooltip(void)
DestroyWindow(parent);
}
+/* try to make sure pending X events have been processed before continuing */
+static void flush_events(int waitTime)
+{
+ MSG msg;
+ int diff = waitTime;
+ DWORD time = GetTickCount() + waitTime;
+
+ while (diff > 0)
+ {
+ if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min(100,diff), QS_ALLEVENTS) == WAIT_TIMEOUT) break;
+ while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ diff = time - GetTickCount();
+ }
+}
+
+static int CD_Stages;
+static LRESULT CD_Result;
+static HWND g_hwnd;
+
+#define TEST_CDDS_PREPAINT 0x00000001
+#define TEST_CDDS_POSTPAINT 0x00000002
+#define TEST_CDDS_PREERASE 0x00000004
+#define TEST_CDDS_POSTERASE 0x00000008
+#define TEST_CDDS_ITEMPREPAINT 0x00000010
+#define TEST_CDDS_ITEMPOSTPAINT 0x00000020
+#define TEST_CDDS_ITEMPREERASE 0x00000040
+#define TEST_CDDS_ITEMPOSTERASE 0x00000080
+#define TEST_CDDS_SUBITEM 0x00000100
+
+static LRESULT CALLBACK CustomDrawWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ case WM_NOTIFY:
+ if (((NMHDR *)lParam)->code == NM_CUSTOMDRAW) {
+ NMTTCUSTOMDRAW *ttcd = (NMTTCUSTOMDRAW*) lParam;
+ ok(ttcd->nmcd.hdr.hwndFrom == g_hwnd, "Unexpected hwnd source %x (%x)\n",
+ (int)ttcd->nmcd.hdr.hwndFrom, (int) g_hwnd);
+ ok(ttcd->nmcd.hdr.idFrom == 0x1234ABCD, "Unexpected id %x\n", (int)ttcd->nmcd.hdr.idFrom);
+
+ switch (ttcd->nmcd.dwDrawStage) {
+ case CDDS_PREPAINT : CD_Stages |= TEST_CDDS_PREPAINT; break;
+ case CDDS_POSTPAINT : CD_Stages |= TEST_CDDS_POSTPAINT; break;
+ case CDDS_PREERASE : CD_Stages |= TEST_CDDS_PREERASE; break;
+ case CDDS_POSTERASE : CD_Stages |= TEST_CDDS_POSTERASE; break;
+ case CDDS_ITEMPREPAINT : CD_Stages |= TEST_CDDS_ITEMPREPAINT; break;
+ case CDDS_ITEMPOSTPAINT: CD_Stages |= TEST_CDDS_ITEMPOSTPAINT; break;
+ case CDDS_ITEMPREERASE : CD_Stages |= TEST_CDDS_ITEMPREERASE; break;
+ case CDDS_ITEMPOSTERASE: CD_Stages |= TEST_CDDS_ITEMPOSTERASE; break;
+ case CDDS_SUBITEM : CD_Stages |= TEST_CDDS_SUBITEM; break;
+ default: CD_Stages = -1;
+ }
+
+ if (ttcd->nmcd.dwDrawStage == CDDS_PREPAINT) return CD_Result;
+ }
+ /* drop through */
+
+ default:
+ return DefWindowProcA(hWnd, msg, wParam, lParam);
+ }
+
+ return 0L;
+}
+
+static void test_customdraw(void) {
+ static struct {
+ LRESULT FirstReturnValue;
+ int ExpectedCalls;
+ } expectedResults[] = {
+ /* Valid notification responses */
+ {CDRF_DODEFAULT, TEST_CDDS_PREPAINT},
+ {CDRF_SKIPDEFAULT, TEST_CDDS_PREPAINT},
+ {CDRF_NOTIFYPOSTPAINT, TEST_CDDS_PREPAINT | TEST_CDDS_POSTPAINT},
+
+ /* Invalid notification responses */
+ {CDRF_NOTIFYITEMDRAW, TEST_CDDS_PREPAINT},
+ {CDRF_NOTIFYPOSTERASE, TEST_CDDS_PREPAINT},
+ {CDRF_NOTIFYSUBITEMDRAW, TEST_CDDS_PREPAINT},
+ {CDRF_NEWFONT, TEST_CDDS_PREPAINT}
+ };
+
+ int iterationNumber;
+ WNDCLASSA wc;
+ LRESULT lResult;
+
+ /* Create a class to use the custom draw wndproc */
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandleA(NULL);
+ wc.hIcon = NULL;
+ wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
+ wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "CustomDrawClass";
+ wc.lpfnWndProc = CustomDrawWndProc;
+ RegisterClass(&wc);
+
+ for (iterationNumber = 0;
+ iterationNumber < sizeof(expectedResults)/sizeof(expectedResults[0]);
+ iterationNumber++) {
+
+ HWND parent, hwndTip;
+ TOOLINFO toolInfo = { 0 };
+
+ /* Create a main window */
+ parent = CreateWindowEx(0, "CustomDrawClass", NULL,
+ WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
+ WS_MAXIMIZEBOX | WS_VISIBLE,
+ 50, 50,
+ 300, 300,
+ NULL, NULL, NULL, 0);
+ ok(parent != NULL, "Creation of main window failed\n");
+
+ /* Make it show */
+ ShowWindow(parent, SW_SHOWNORMAL);
+ flush_events(100);
+
+ /* Create Tooltip */
+ hwndTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS,
+ NULL, TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ parent, NULL, GetModuleHandleA(NULL), 0);
+ ok(hwndTip != NULL, "Creation of tooltip window failed\n");
+
+ /* Set up parms for the wndproc to handle */
+ CD_Stages = 0;
+ CD_Result = expectedResults[iterationNumber].FirstReturnValue;
+ g_hwnd = hwndTip;
+
+ /* Make it topmost, as per the MSDN */
+ SetWindowPos(hwndTip, HWND_TOPMOST, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ /* Create a tool */
+ toolInfo.cbSize = sizeof(TOOLINFO);
+ toolInfo.hwnd = parent;
+ toolInfo.hinst = GetModuleHandleA(NULL);
+ toolInfo.uFlags = TTF_SUBCLASS;
+ toolInfo.uId = (UINT_PTR)0x1234ABCD;
+ toolInfo.lpszText = (LPSTR)"This is a test tooltip";
+ toolInfo.lParam = 0xdeadbeef;
+ GetClientRect (parent, &toolInfo.rect);
+ lResult = SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
+ ok(lResult, "Adding the tool to the tooltip failed\n");
+
+ /* Make tooltip appear quickly */
+ SendMessage(hwndTip, TTM_SETDELAYTIME, (WPARAM)TTDT_INITIAL, (LPARAM)MAKELONG(1,0));
+
+ /* Put cursor inside window, tooltip will appear immediately */
+ SetCursorPos(100, 100);
+ flush_events(200);
+
+ /* Check CustomDraw results */
+ ok(CD_Stages == expectedResults[iterationNumber].ExpectedCalls,
+ "CustomDraw run %d stages %x, expected %x\n", iterationNumber, CD_Stages,
+ expectedResults[iterationNumber].ExpectedCalls);
+
+ /* Clean up */
+ DestroyWindow(hwndTip);
+ DestroyWindow(parent);
+ }
+
+
+}
+
START_TEST(tooltips)
{
InitCommonControls();
test_create_tooltip();
+ test_customdraw();
}
diff --git a/rostests/winetests/comctl32/treeview.c b/rostests/winetests/comctl32/treeview.c
index 93010d3065e..c1ba7f309be 100644
--- a/rostests/winetests/comctl32/treeview.c
+++ b/rostests/winetests/comctl32/treeview.c
@@ -649,10 +649,23 @@ static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
START_TEST(treeview)
{
+ HMODULE hComctl32;
+ BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
WNDCLASSA wc;
MSG msg;
- InitCommonControls();
+ hComctl32 = GetModuleHandleA("comctl32.dll");
+ pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
+ if (pInitCommonControlsEx)
+ {
+ INITCOMMONCONTROLSEX iccex;
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_TREEVIEW_CLASSES;
+ pInitCommonControlsEx(&iccex);
+ }
+ else
+ InitCommonControls();
+
init_msg_sequences(MsgSequences, NUM_MSG_SEQUENCES);
wc.style = CS_HREDRAW | CS_VREDRAW;
diff --git a/rostests/winetests/comdlg32/comdlg32.rbuild b/rostests/winetests/comdlg32/comdlg32.rbuild
index fc3c02ecb86..c29c693fa99 100644
--- a/rostests/winetests/comdlg32/comdlg32.rbuild
+++ b/rostests/winetests/comdlg32/comdlg32.rbuild
@@ -1,15 +1,17 @@
+
.
0x600
0x600
+ filedlg.c
+ printdlg.c
+ testlist.c
wine
comdlg32
user32
kernel32
ntdll
- filedlg.c
- printdlg.c
- testlist.c
+
diff --git a/rostests/winetests/comdlg32/printdlg.c b/rostests/winetests/comdlg32/printdlg.c
index 783773f1adc..744b6eb456f 100644
--- a/rostests/winetests/comdlg32/printdlg.c
+++ b/rostests/winetests/comdlg32/printdlg.c
@@ -26,6 +26,7 @@
#include "winerror.h"
#include "wingdi.h"
#include "winuser.h"
+#include "objbase.h"
#include "cderr.h"
#include "commdlg.h"
diff --git a/rostests/winetests/directory.rbuild b/rostests/winetests/directory.rbuild
index 34fed194b83..7ec4c4153dc 100644
--- a/rostests/winetests/directory.rbuild
+++ b/rostests/winetests/directory.rbuild
@@ -31,6 +31,9 @@
+
+
+
@@ -73,6 +76,9 @@
+
+
+
diff --git a/rostests/winetests/hlink/hlink.c b/rostests/winetests/hlink/hlink.c
index a2d7360a47d..6c3dff0591a 100644
--- a/rostests/winetests/hlink/hlink.c
+++ b/rostests/winetests/hlink/hlink.c
@@ -2,7 +2,7 @@
* Implementation of hyperlinking (hlink.dll)
*
* Copyright 2006 Mike McCormack
- * Copyright 2007 Jacek Caban for CodeWeavers
+ * Copyright 2007-2008 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,34 @@
#include "wine/test.h"
+#define DEFINE_EXPECT(func) \
+ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+ expect_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+ do { \
+ ok(expect_ ##func, "unexpected call " #func "\n"); \
+ called_ ## func = TRUE; \
+ }while(0)
+
+#define CHECK_EXPECT(func) \
+ do { \
+ CHECK_EXPECT2(func); \
+ expect_ ## func = FALSE; \
+ }while(0)
+
+#define CHECK_CALLED(func) \
+ do { \
+ ok(called_ ## func, "expected " #func "\n"); \
+ expect_ ## func = called_ ## func = FALSE; \
+ }while(0)
+
+DEFINE_EXPECT(IsSystemMoniker);
+DEFINE_EXPECT(BindToStorage);
+DEFINE_EXPECT(GetDisplayName);
+
static const char *debugstr_w(LPCWSTR str)
{
static char buf[1024];
@@ -37,6 +65,18 @@ static const char *debugstr_w(LPCWSTR str)
return buf;
}
+static const char *debugstr_guid(REFIID riid)
+{
+ static char buf[50];
+
+ sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
+ riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
+ riid->Data4[5], riid->Data4[6], riid->Data4[7]);
+
+ return buf;
+}
+
static void test_HlinkIsShortcut(void)
{
int i;
@@ -292,7 +332,11 @@ static void test_persist(void)
hr = HlinkCreateFromString(url, NULL, NULL, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &lnk);
- ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
+ ok(hr == S_OK, "IHlinkCreateFromString failed with error 0x%08x\n", hr);
+ if (!lnk) {
+ skip("Can't create lnk, skipping test_persist. Was wineprefixcreate run properly?\n");
+ return;
+ }
test_persist_save_data("url only", lnk, expected_hlink_data, sizeof(expected_hlink_data));
IHlink_Release(lnk);
@@ -444,6 +488,422 @@ static void test_HlinkCreateExtensionServices(void)
IAuthenticate_Release(authenticate);
}
+static void test_HlinkParseDisplayName(void)
+{
+ IMoniker *mon = NULL;
+ LPWSTR name;
+ DWORD issys;
+ ULONG eaten = 0;
+ IBindCtx *bctx;
+ HRESULT hres;
+
+ static const WCHAR winehq_urlW[] =
+ {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
+ '/','s','i','t','e','/','a','b','o','u','t',0};
+ static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
+ static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
+ '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
+ '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
+
+ CreateBindCtx(0, &bctx);
+
+ hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
+ ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
+ ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+ ok(mon != NULL, "mon == NULL\n");
+
+ hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
+ ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
+ ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", debugstr_w(name));
+ CoTaskMemFree(name);
+
+ hres = IMoniker_IsSystemMoniker(mon, &issys);
+ ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
+ ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
+
+ IMoniker_Release(mon);
+
+ hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
+ ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
+ ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+ ok(mon != NULL, "mon == NULL\n");
+
+ hres = IMoniker_IsSystemMoniker(mon, &issys);
+ ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
+ ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
+
+ IMoniker_Release(mon);
+
+ hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
+ ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
+ ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+ ok(mon != NULL, "mon == NULL\n");
+
+ hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
+ ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
+ ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", debugstr_w(name));
+ CoTaskMemFree(name);
+
+ hres = IMoniker_IsSystemMoniker(mon, &issys);
+ ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
+ ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
+
+ IBindCtx_Release(bctx);
+}
+
+static IBindCtx *_bctx;
+
+static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected call\n");
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
+ REFGUID guidService, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected service %s\n", debugstr_guid(guidService));
+ return E_NOINTERFACE;
+}
+
+static IServiceProviderVtbl ServiceProviderVtbl = {
+ ServiceProvider_QueryInterface,
+ ServiceProvider_AddRef,
+ ServiceProvider_Release,
+ ServiceProvider_QueryService
+};
+
+static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
+
+static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ if(IsEqualGUID(riid, &IID_IServiceProvider)) {
+ *ppv = &ServiceProvider;
+ return S_OK;
+ }
+
+ ok(0, "unexpected interface %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
+ IBinding *pib)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
+ ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
+ DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
+ BindStatusCallback_QueryInterface,
+ BindStatusCallback_AddRef,
+ BindStatusCallback_Release,
+ BindStatusCallback_OnStartBinding,
+ BindStatusCallback_GetPriority,
+ BindStatusCallback_OnLowResource,
+ BindStatusCallback_OnProgress,
+ BindStatusCallback_OnStopBinding,
+ BindStatusCallback_GetBindInfo,
+ BindStatusCallback_OnDataAvailable,
+ BindStatusCallback_OnObjectAvailable
+};
+
+static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
+
+static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ ok(0, "unexpected riid: %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI Moniker_Release(IMoniker *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pcb, IMoniker *pmkToLeft,
+ REFIID riidResult, void **ppvResult)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
+ REFIID riid, void **ppv)
+{
+ IUnknown *unk;
+ HRESULT hres;
+
+ static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
+
+ CHECK_EXPECT(BindToStorage);
+
+ ok(pbc == _bctx, "pbc != _bctx\n");
+ ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
+ ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
+ ok(ppv != NULL, "ppv == NULL\n");
+ ok(*ppv == NULL, "*ppv=%p\n", *ppv);
+
+ hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
+ ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
+ ok(unk != NULL, "unk == NULL\n");
+
+ IUnknown_Release(unk);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
+ IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
+ BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
+ IMoniker *pmkNewlyRunning)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
+ IMoniker *pmkToLeft, FILETIME *pFileTime)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
+ IMoniker **ppmkPrefix)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
+ IMoniker **pmkRelPath)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
+ IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
+{
+ static const WCHAR winehq_urlW[] =
+ {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
+ '/','s','i','t','e','/','a','b','o','u','t',0};
+
+ CHECK_EXPECT(GetDisplayName);
+
+ ok(pbc != NULL, "pbc == NULL\n");
+ ok(pbc != _bctx, "pbc == _bctx\n");
+ ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
+
+ *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
+ memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
+ return S_OK;
+}
+
+static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
+ IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
+{
+ CHECK_EXPECT2(IsSystemMoniker);
+
+ *pdwMksys = MKSYS_URLMONIKER;
+ return S_OK;
+}
+
+static IMonikerVtbl MonikerVtbl = {
+ Moniker_QueryInterface,
+ Moniker_AddRef,
+ Moniker_Release,
+ Moniker_GetClassID,
+ Moniker_IsDirty,
+ Moniker_Load,
+ Moniker_Save,
+ Moniker_GetSizeMax,
+ Moniker_BindToObject,
+ Moniker_BindToStorage,
+ Moniker_Reduce,
+ Moniker_ComposeWith,
+ Moniker_Enum,
+ Moniker_IsEqual,
+ Moniker_Hash,
+ Moniker_IsRunning,
+ Moniker_GetTimeOfLastChange,
+ Moniker_Inverse,
+ Moniker_CommonPrefixWith,
+ Moniker_RelativePathTo,
+ Moniker_GetDisplayName,
+ Moniker_ParseDisplayName,
+ Moniker_IsSystemMoniker
+};
+
+static IMoniker Moniker = { &MonikerVtbl };
+
+static void test_HlinkResolveMonikerForData(void)
+{
+ IBindCtx *bctx;
+ HRESULT hres;
+
+ CreateBindCtx(0, &bctx);
+ _bctx = bctx;
+
+ SET_EXPECT(IsSystemMoniker);
+ SET_EXPECT(GetDisplayName);
+ SET_EXPECT(BindToStorage);
+
+ hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
+ ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
+
+ CHECK_CALLED(IsSystemMoniker);
+ CHECK_CALLED(GetDisplayName);
+ CHECK_CALLED(BindToStorage);
+
+ IBindCtx_Release(bctx);
+}
+
START_TEST(hlink)
{
CoInitialize(NULL);
@@ -453,6 +913,8 @@ START_TEST(hlink)
test_persist();
test_special_reference();
test_HlinkCreateExtensionServices();
+ test_HlinkParseDisplayName();
+ test_HlinkResolveMonikerForData();
CoUninitialize();
}
diff --git a/rostests/winetests/hlink/hlink.rbuild b/rostests/winetests/hlink/hlink.rbuild
index de30316adcf..a66a08a7310 100644
--- a/rostests/winetests/hlink/hlink.rbuild
+++ b/rostests/winetests/hlink/hlink.rbuild
@@ -5,13 +5,13 @@
.
0x600
0x600
+ hlink.c
+ testlist.c
wine
hlink
ole32
kernel32
uuid
ntdll
- hlink.c
- testlist.c
diff --git a/rostests/winetests/imm32/imm32.c b/rostests/winetests/imm32/imm32.c
new file mode 100644
index 00000000000..d948f548895
--- /dev/null
+++ b/rostests/winetests/imm32/imm32.c
@@ -0,0 +1,218 @@
+/*
+ * Unit tests for imm32
+ *
+ * Copyright (c) 2008 Michael Jung
+ *
+ * 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
+
+#include "wine/test.h"
+#include "winuser.h"
+#include "imm.h"
+
+#define NUMELEMS(array) (sizeof((array))/sizeof((array)[0]))
+
+/*
+ * msgspy - record and analyse message traces sent to a certain window
+ */
+static struct _msg_spy {
+ HWND hwnd;
+ HHOOK get_msg_hook;
+ HHOOK call_wnd_proc_hook;
+ CWPSTRUCT msgs[32];
+ unsigned int i_msg;
+} msg_spy;
+
+static LRESULT CALLBACK get_msg_filter(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ if (HC_ACTION == nCode) {
+ MSG *msg = (MSG*)lParam;
+
+ if ((msg->hwnd == msg_spy.hwnd) &&
+ (msg_spy.i_msg < NUMELEMS(msg_spy.msgs)))
+ {
+ msg_spy.msgs[msg_spy.i_msg].hwnd = msg->hwnd;
+ msg_spy.msgs[msg_spy.i_msg].message = msg->message;
+ msg_spy.msgs[msg_spy.i_msg].wParam = msg->wParam;
+ msg_spy.msgs[msg_spy.i_msg].lParam = msg->lParam;
+ msg_spy.i_msg++;
+ }
+ }
+
+ return CallNextHookEx(msg_spy.get_msg_hook, nCode, wParam, lParam);
+}
+
+static LRESULT CALLBACK call_wnd_proc_filter(int nCode, WPARAM wParam,
+ LPARAM lParam)
+{
+ if (HC_ACTION == nCode) {
+ CWPSTRUCT *cwp = (CWPSTRUCT*)lParam;
+
+ if ((cwp->hwnd == msg_spy.hwnd) &&
+ (msg_spy.i_msg < NUMELEMS(msg_spy.msgs)))
+ {
+ memcpy(&msg_spy.msgs[msg_spy.i_msg], cwp, sizeof(msg_spy.msgs[0]));
+ msg_spy.i_msg++;
+ }
+ }
+
+ return CallNextHookEx(msg_spy.call_wnd_proc_hook, nCode, wParam, lParam);
+}
+
+static void msg_spy_pump_msg_queue(void) {
+ MSG msg;
+
+ while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return;
+}
+
+static void msg_spy_flush_msgs(void) {
+ msg_spy_pump_msg_queue();
+ msg_spy.i_msg = 0;
+}
+
+static CWPSTRUCT* msg_spy_find_msg(UINT message) {
+ int i;
+
+ msg_spy_pump_msg_queue();
+
+ if (msg_spy.i_msg >= NUMELEMS(msg_spy.msgs))
+ fprintf(stdout, "%s:%d: msg_spy: message buffer overflow!\n",
+ __FILE__, __LINE__);
+
+ for (i = 0; i < msg_spy.i_msg; i++)
+ if (msg_spy.msgs[i].message == message)
+ return &msg_spy.msgs[i];
+
+ return NULL;
+}
+
+static void msg_spy_init(HWND hwnd) {
+ msg_spy.hwnd = hwnd;
+ msg_spy.get_msg_hook =
+ SetWindowsHookEx(WH_GETMESSAGE, get_msg_filter, GetModuleHandle(0),
+ GetCurrentThreadId());
+ msg_spy.call_wnd_proc_hook =
+ SetWindowsHookEx(WH_CALLWNDPROC, call_wnd_proc_filter,
+ GetModuleHandle(0), GetCurrentThreadId());
+ msg_spy.i_msg = 0;
+
+ msg_spy_flush_msgs();
+}
+
+static void msg_spy_cleanup() {
+ if (msg_spy.get_msg_hook)
+ UnhookWindowsHookEx(msg_spy.get_msg_hook);
+ if (msg_spy.call_wnd_proc_hook)
+ UnhookWindowsHookEx(msg_spy.call_wnd_proc_hook);
+ memset(&msg_spy, 0, sizeof(msg_spy));
+}
+
+/*
+ * imm32 test cases - Issue some IMM commands on a dummy window and analyse the
+ * messages being sent to this window in response.
+ */
+static const char wndcls[] = "winetest_imm32_wndcls";
+static HWND hwnd;
+
+static int init(void) {
+ WNDCLASSEX wc;
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = 0;
+ wc.lpfnWndProc = DefWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(0);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = wndcls;
+ wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+
+ if (!RegisterClassExA(&wc))
+ return 0;
+
+ hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 120, NULL, NULL, GetModuleHandle(0), NULL);
+ if (!hwnd)
+ return 0;
+
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ UpdateWindow(hwnd);
+
+ msg_spy_init(hwnd);
+
+ return 1;
+}
+
+static void cleanup(void) {
+ msg_spy_cleanup();
+ if (hwnd)
+ DestroyWindow(hwnd);
+ UnregisterClass(wndcls, GetModuleHandle(0));
+}
+
+static int test_ImmNotifyIME(void) {
+ static const char string[] = "wine";
+ char resstr[16] = "";
+ HIMC imc;
+
+ imc = ImmGetContext(hwnd);
+ msg_spy_flush_msgs();
+
+ ok(ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0), "Canceling an "
+ "empty composition string succeeds.\n");
+ ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
+ "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
+ "the composition string being canceled is empty.\n");
+
+ msg_spy_flush_msgs();
+
+ ImmSetCompositionString(imc, SCS_SETSTR, string, sizeof(string), NULL, 0);
+ ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
+ ok(msg_spy_find_msg(WM_IME_COMPOSITION) != NULL, "Windows does post "
+ "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
+ "the composition string being canceled is non empty.\n");
+ ok(!ImmGetCompositionString(imc, GCS_COMPSTR, resstr, sizeof(resstr)),
+ "After being canceled the composition string is empty.\n");
+
+ msg_spy_flush_msgs();
+
+ ok(ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0), "Canceling an "
+ "empty composition string succeeds.\n");
+ ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
+ "WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
+ "the composition string being canceled is empty.\n");
+
+ msg_spy_flush_msgs();
+ ImmReleaseContext(hwnd, imc);
+
+ return 0;
+}
+
+START_TEST(imm32) {
+ if (init())
+ test_ImmNotifyIME();
+ cleanup();
+}
diff --git a/rostests/winetests/imm32/imm32.rbuild b/rostests/winetests/imm32/imm32.rbuild
new file mode 100644
index 00000000000..e61c139be59
--- /dev/null
+++ b/rostests/winetests/imm32/imm32.rbuild
@@ -0,0 +1,16 @@
+
+
+
+
+ .
+ 0x600
+ 0x600
+ imm32.c
+ testlist.c
+ wine
+ imm32
+ user32
+ kernel32
+ ntdll
+
+
diff --git a/rostests/winetests/imm32/testlist.c b/rostests/winetests/imm32/testlist.c
new file mode 100644
index 00000000000..a7911d1b0e0
--- /dev/null
+++ b/rostests/winetests/imm32/testlist.c
@@ -0,0 +1,15 @@
+/* Automatically generated file; DO NOT EDIT!! */
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+#define STANDALONE
+#include "wine/test.h"
+
+extern void func_imm32(void);
+
+const struct test winetest_testlist[] =
+{
+ { "imm32", func_imm32 },
+ { 0, 0 }
+};
diff --git a/rostests/winetests/lz32/lz32.rbuild b/rostests/winetests/lz32/lz32.rbuild
index abe12d9353b..a9e500a7d23 100644
--- a/rostests/winetests/lz32/lz32.rbuild
+++ b/rostests/winetests/lz32/lz32.rbuild
@@ -1,13 +1,15 @@
+
.
0x600
0x600
+ lzexpand_main.c
+ testlist.c
wine
lz32
kernel32
ntdll
- lzexpand_main.c
- testlist.c
+
diff --git a/rostests/winetests/lz32/lzexpand_main.c b/rostests/winetests/lz32/lzexpand_main.c
index b51067bcff3..c67883acb54 100644
--- a/rostests/winetests/lz32/lzexpand_main.c
+++ b/rostests/winetests/lz32/lzexpand_main.c
@@ -54,10 +54,7 @@ static char filename2[] = "testfile.yyy";
a simple text file with the contents "This is a test file."
The file was created using COMPRESS.EXE from the Windows Server 2003
- Resource Kit from Microsoft. The resource kit was retrieved from the
- following URL:
-
- http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en
+ Resource Kit from Microsoft.
*/
static const unsigned char compressed_file[] =
{0x53,0x5A,0x44,0x44,0x88,0xF0,0x27,0x33,0x41,
diff --git a/rostests/winetests/mapi32/mapi32.rbuild b/rostests/winetests/mapi32/mapi32.rbuild
index 8712bb2a28d..6da38a35bc5 100644
--- a/rostests/winetests/mapi32/mapi32.rbuild
+++ b/rostests/winetests/mapi32/mapi32.rbuild
@@ -1,15 +1,17 @@
+
.
0x600
0x600
- wine
- kernel32
- uuid
- ntdll
imalloc.c
prop.c
util.c
testlist.c
+ wine
+ kernel32
+ uuid
+ ntdll
+
diff --git a/rostests/winetests/mapi32/prop.c b/rostests/winetests/mapi32/prop.c
index d78eb3697f3..adc1d85b91a 100644
--- a/rostests/winetests/mapi32/prop.c
+++ b/rostests/winetests/mapi32/prop.c
@@ -24,6 +24,7 @@
#include "winuser.h"
#include "winerror.h"
#include "winnt.h"
+#include "initguid.h"
#include "mapiutil.h"
#include "mapitags.h"
diff --git a/rostests/winetests/mlang/mlang.rbuild b/rostests/winetests/mlang/mlang.rbuild
index 748cb29d283..2f508f5ad8f 100644
--- a/rostests/winetests/mlang/mlang.rbuild
+++ b/rostests/winetests/mlang/mlang.rbuild
@@ -1,15 +1,17 @@
+
.
0x600
0x600
+ mlang.c
+ testlist.c
wine
ole32
gdi32
kernel32
uuid
ntdll
- mlang.c
- testlist.c
+
diff --git a/rostests/winetests/msi/automation.c b/rostests/winetests/msi/automation.c
index 90e4b1f62b0..f2e5c13abe4 100644
--- a/rostests/winetests/msi/automation.c
+++ b/rostests/winetests/msi/automation.c
@@ -465,85 +465,138 @@ static DISPID get_dispid( IDispatch *disp, const char *name )
static void test_dispid(void)
{
- ok( get_dispid( pInstaller, "CreateRecord" ) == 1, "dispid wrong\n");
- ok( get_dispid( pInstaller, "OpenPackage" ) == 2, "dispid wrong\n");
- todo_wine ok( get_dispid( pInstaller, "OpenProduct" ) == 3, "dispid wrong\n");
- ok( get_dispid( pInstaller, "OpenDatabase" ) == 4, "dispid wrong\n");
- todo_wine {
- ok( get_dispid( pInstaller, "SummaryInformation" ) == 5, "dispid wrong\n");
- ok( get_dispid( pInstaller, "UILevel" ) == 6, "dispid wrong\n");
- ok( get_dispid( pInstaller, "EnableLog" ) == 7, "dispid wrong\n");
- }
- ok( get_dispid( pInstaller, "InstallProduct" ) == 8, "dispid wrong\n");
- ok( get_dispid( pInstaller, "Version" ) == 9, "dispid wrong\n");
- todo_wine {
- ok( get_dispid( pInstaller, "LastErrorRecord" ) == 10, "dispid wrong\n");
- }
- ok( get_dispid( pInstaller, "RegistryValue" ) == 11, "dispid wrong\n");
- todo_wine {
- ok( get_dispid( pInstaller, "Environment" ) == 12, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FileAttributes" ) == 13, "dispid wrong\n");
+ DISPID dispid;
- ok( get_dispid( pInstaller, "FileSize" ) == 15, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FileVersion" ) == 16, "dispid wrong\n");
+ dispid = get_dispid(pInstaller, "CreateRecord");
+ ok(dispid == 1, "Expected 1, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "OpenPackage");
+ ok(dispid == 2, "Expected 2, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "OpenDatabase");
+ ok(dispid == 4, "Expected 4, got %d\n", dispid);
+ dispid = get_dispid( pInstaller, "UILevel" );
+ ok(dispid == 6, "Expected 6, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "InstallProduct");
+ ok(dispid == 8, "Expected 8, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "Version");
+ ok(dispid == 9, "Expected 9, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "RegistryValue");
+ ok(dispid == 11, "Expected 11, got %d\n", dispid);
+ todo_wine
+ {
+ dispid = get_dispid(pInstaller, "OpenProduct");
+ ok(dispid == 3, "Expected 3, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "SummaryInformation");
+ ok(dispid == 5, "Expected 5, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "EnableLog");
+ ok(dispid == 7, "Expected 7, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "LastErrorRecord");
+ ok(dispid == 10, "Expected 10, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "Environment");
+ ok(dispid == 12, "Expected 12, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FileAttributes");
+ ok(dispid == 13, "Expected 13, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FileSize");
+ ok(dispid == 15, "Expected 15, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FileVersion");
+ ok(dispid == 16, "Expected 16, got %d\n", dispid);
}
- ok( get_dispid( pInstaller, "ProductState" ) == 17, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ProductInfo" ) == 18, "dispid wrong\n");
- todo_wine {
- ok( get_dispid( pInstaller, "ConfigureProduct" ) == 19, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ReinstallProduct" ) == 20 , "dispid wrong\n");
- ok( get_dispid( pInstaller, "CollectUserInfo" ) == 21, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ApplyPatch" ) == 22, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FeatureParent" ) == 23, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FeatureState" ) == 24, "dispid wrong\n");
- ok( get_dispid( pInstaller, "UseFeature" ) == 25, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FeatureUsageCount" ) == 26, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FeatureUsageDate" ) == 27, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ConfigureFeature" ) == 28, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ReinstallFeature" ) == 29, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ProvideComponent" ) == 30, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ComponentPath" ) == 31, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ProvideQualifiedComponent" ) == 32, "dispid wrong\n");
- ok( get_dispid( pInstaller, "QualifierDescription" ) == 33, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ComponentQualifiers" ) == 34, "dispid wrong\n");
+ dispid = get_dispid(pInstaller, "ProductState");
+ ok(dispid == 17, "Expected 17, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ProductInfo");
+ ok(dispid == 18, "Expected 18, got %d\n", dispid);
+ todo_wine
+ {
+ dispid = get_dispid(pInstaller, "ConfigureProduct");
+ ok(dispid == 19, "Expected 19, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ReinstallProduct");
+ ok(dispid == 20 , "Expected 20, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "CollectUserInfo");
+ ok(dispid == 21, "Expected 21, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ApplyPatch");
+ ok(dispid == 22, "Expected 22, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FeatureParent");
+ ok(dispid == 23, "Expected 23, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FeatureState");
+ ok(dispid == 24, "Expected 24, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "UseFeature");
+ ok(dispid == 25, "Expected 25, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FeatureUsageCount");
+ ok(dispid == 26, "Expected 26, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FeatureUsageDate");
+ ok(dispid == 27, "Expected 27, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ConfigureFeature");
+ ok(dispid == 28, "Expected 28, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ReinstallFeature");
+ ok(dispid == 29, "Expected 29, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ProvideComponent");
+ ok(dispid == 30, "Expected 30, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ComponentPath");
+ ok(dispid == 31, "Expected 31, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ProvideQualifiedComponent");
+ ok(dispid == 32, "Expected 32, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "QualifierDescription");
+ ok(dispid == 33, "Expected 33, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ComponentQualifiers");
+ ok(dispid == 34, "Expected 34, got %d\n", dispid);
}
- ok( get_dispid( pInstaller, "Products" ) == 35, "dispid wrong\n");
- todo_wine {
- ok( get_dispid( pInstaller, "Features" ) == 36, "dispid wrong\n");
- ok( get_dispid( pInstaller, "Components" ) == 37, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ComponentClients" ) == 38, "dispid wrong\n");
- ok( get_dispid( pInstaller, "Patches" ) == 39, "dispid wrong\n");
+ dispid = get_dispid(pInstaller, "Products");
+ ok(dispid == 35, "Expected 35, got %d\n", dispid);
+ todo_wine
+ {
+ dispid = get_dispid(pInstaller, "Features");
+ ok(dispid == 36, "Expected 36, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "Components");
+ ok(dispid == 37, "Expected 37, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ComponentClients");
+ ok(dispid == 38, "Expected 38, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "Patches");
+ ok(dispid == 39, "Expected 39, got %d\n", dispid);
}
- ok( get_dispid( pInstaller, "RelatedProducts" ) == 40, "dispid wrong\n");
- todo_wine {
- ok( get_dispid( pInstaller, "PatchInfo" ) == 41, "dispid wrong\n");
- ok( get_dispid( pInstaller, "PatchTransforms" ) == 42, "dispid wrong\n");
- ok( get_dispid( pInstaller, "AddSource" ) == 43, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ClearSourceList" ) == 44, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ForceSourceListResolution" ) == 45, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ShortcutTarget" ) == 46, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FileHash" ) == 47, "dispid wrong\n");
- ok( get_dispid( pInstaller, "FileSignatureInfo" ) == 48, "dispid wrong\n");
- ok( get_dispid( pInstaller, "RemovePatches" ) == 49, "dispid wrong\n");
-
- ok( get_dispid( pInstaller, "ApplyMultiplePatches" ) == 51, "dispid wrong\n");
- ok( get_dispid( pInstaller, "ProductsEx" ) == 52, "dispid wrong\n");
-
- ok( get_dispid( pInstaller, "PatchesEx" ) == 55, "dispid wrong\n");
-
- ok( get_dispid( pInstaller, "ExtractPatchXMLData" ) == 57, "dispid wrong\n");
+ dispid = get_dispid(pInstaller, "RelatedProducts");
+ ok(dispid == 40, "Expected 40, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "RemovePatches");
+ ok(dispid == 49 || dispid == -1, "Expected 49 or -1, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ApplyMultiplePatches");
+ ok(dispid == 51 || dispid == -1, "Expected 51 or -1, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ProductsEx");
+ ok(dispid == 52 || dispid == -1, "Expected 52 or -1, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "PatchesEx");
+ ok(dispid == 55 || dispid == -1, "Expected 55 or -1, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ExtractPatchXMLData");
+ ok(dispid == 57 || dispid == -1, "Expected 57 or -1, got %d\n", dispid);
+ todo_wine
+ {
+ dispid = get_dispid(pInstaller, "PatchInfo");
+ ok(dispid == 41, "Expected 41, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "PatchTransforms");
+ ok(dispid == 42, "Expected 42, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "AddSource");
+ ok(dispid == 43, "Expected 43, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ClearSourceList");
+ ok(dispid == 44, "Expected 44, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ForceSourceListResolution");
+ ok(dispid == 45, "Expected 45, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "ShortcutTarget");
+ ok(dispid == 46, "Expected 46, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FileHash");
+ ok(dispid == 47, "Expected 47, got %d\n", dispid);
+ dispid = get_dispid(pInstaller, "FileSignatureInfo");
+ ok(dispid == 48, "Expected 48, got %d\n", dispid);
}
/* MSDN claims the following functions exist but IDispatch->GetIDsOfNames disagrees */
- if (0)
- {
- get_dispid( pInstaller, "ProductElevated" );
- get_dispid( pInstaller, "ProductInfoFromScript" );
- get_dispid( pInstaller, "ProvideAssembly" );
- get_dispid( pInstaller, "CreateAdvertiseScript" );
- get_dispid( pInstaller, "AdvertiseProduct" );
- get_dispid( pInstaller, "PatchFiles" );
- }
+ dispid = get_dispid( pInstaller, "ProductElevated" );
+ ok(dispid == -1, "Expected -1, got %d\n", dispid);
+ dispid = get_dispid( pInstaller, "ProductInfoFromScript" );
+ ok(dispid == -1, "Expected -1, got %d\n", dispid);
+ dispid = get_dispid( pInstaller, "ProvideAssembly" );
+ ok(dispid == -1, "Expected -1, got %d\n", dispid);
+ dispid = get_dispid( pInstaller, "CreateAdvertiseScript" );
+ ok(dispid == -1, "Expected -1, got %d\n", dispid);
+ dispid = get_dispid( pInstaller, "AdvertiseProduct" );
+ ok(dispid == -1, "Expected -1, got %d\n", dispid);
+ dispid = get_dispid( pInstaller, "PatchFiles" );
+ ok(dispid == -1, "Expected -1, got %d\n", dispid);
}
/* Test basic IDispatch functions */
@@ -1526,10 +1579,8 @@ static void test_Database(IDispatch *pDatabase, BOOL readonly)
ok(hr == DISP_E_EXCEPTION, "View_Modify failed, hresult 0x%08x\n", hr);
ok_exception(hr, szModifyModeRecord);
- /* View::Modify with MSIMODIFY_REFRESH should undo our changes */
hr = View_Modify(pView, MSIMODIFY_REFRESH, pRecord);
- /* Wine's MsiViewModify currently does not support MSIMODIFY_REFRESH */
- todo_wine ok(hr == S_OK, "View_Modify failed, hresult 0x%08x\n", hr);
+ ok(hr == S_OK, "View_Modify failed, hresult 0x%08x\n", hr);
/* Record::StringDataGet, confirm that the record is back to its unmodified value */
memset(szString, 0, sizeof(szString));
@@ -1762,6 +1813,7 @@ static void test_Installer_RegistryValue(void)
VARIANTARG vararg;
WCHAR szString[MAX_PATH];
HKEY hkey, hkey_sub;
+ HKEY curr_user = (HKEY)1;
HRESULT hr;
BOOL bRet;
@@ -1769,16 +1821,16 @@ static void test_Installer_RegistryValue(void)
if (!RegOpenKeyW( HKEY_CURRENT_USER, szKey, &hkey )) delete_key( hkey );
/* Does our key exist? Shouldn't; check with all three possible value parameter types */
- hr = Installer_RegistryValueE(HKEY_CURRENT_USER, szKey, &bRet);
+ hr = Installer_RegistryValueE(curr_user, szKey, &bRet);
ok(hr == S_OK, "Installer_RegistryValueE failed, hresult 0x%08x\n", hr);
ok(!bRet, "Registry key expected to not exist, but Installer_RegistryValue claims it does\n");
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, NULL, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, NULL, szString);
ok(hr == DISP_E_BADINDEX, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueI(HKEY_CURRENT_USER, szKey, 0, szString, VT_BSTR);
+ hr = Installer_RegistryValueI(curr_user, szKey, 0, szString, VT_BSTR);
ok(hr == DISP_E_BADINDEX, "Installer_RegistryValueI failed, hresult 0x%08x\n", hr);
/* Create key */
@@ -1807,87 +1859,87 @@ static void test_Installer_RegistryValue(void)
/* Does our key exist? It should, and make sure we retrieve the correct default value */
bRet = FALSE;
- hr = Installer_RegistryValueE(HKEY_CURRENT_USER, szKey, &bRet);
+ hr = Installer_RegistryValueE(curr_user, szKey, &bRet);
ok(hr == S_OK, "Installer_RegistryValueE failed, hresult 0x%08x\n", hr);
ok(bRet, "Registry key expected to exist, but Installer_RegistryValue claims it does not\n");
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, NULL, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, NULL, szString);
ok(hr == S_OK, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
ok_w2("Default registry value \"%s\" does not match expected \"%s\"\n", szString, szOne);
/* Ask for the value of a nonexistent key */
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, szExpand, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, szExpand, szString);
ok(hr == DISP_E_BADINDEX, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
/* Get values of keys */
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, szOne, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, szOne, szString);
ok(hr == S_OK, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, szOne);
VariantInit(&vararg);
V_VT(&vararg) = VT_BSTR;
V_BSTR(&vararg) = SysAllocString(szTwo);
- hr = Installer_RegistryValue(HKEY_CURRENT_USER, szKey, vararg, &varresult, VT_I4);
+ hr = Installer_RegistryValue(curr_user, szKey, vararg, &varresult, VT_I4);
ok(hr == S_OK, "Installer_RegistryValue failed, hresult 0x%08x\n", hr);
ok(V_I4(&varresult) == 305419896, "Registry value %d does not match expected value\n", V_I4(&varresult));
VariantClear(&varresult);
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, szThree, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, szThree, szString);
ok(hr == S_OK, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, szREG_BINARY);
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, szFour, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, szFour, szString);
ok(hr == S_OK, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, szFour);
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, szFive, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, szFive, szString);
ok(hr == S_OK, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, szFiveHi);
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueW(HKEY_CURRENT_USER, szKey, szSix, szString);
+ hr = Installer_RegistryValueW(curr_user, szKey, szSix, szString);
ok(hr == S_OK, "Installer_RegistryValueW failed, hresult 0x%08x\n", hr);
ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, szREG_);
VariantInit(&vararg);
V_VT(&vararg) = VT_BSTR;
V_BSTR(&vararg) = SysAllocString(szSeven);
- hr = Installer_RegistryValue(HKEY_CURRENT_USER, szKey, vararg, &varresult, VT_EMPTY);
+ hr = Installer_RegistryValue(curr_user, szKey, vararg, &varresult, VT_EMPTY);
ok(hr == S_OK, "Installer_RegistryValue failed, hresult 0x%08x\n", hr);
/* Get string class name for the key */
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueI(HKEY_CURRENT_USER, szKey, 0, szString, VT_BSTR);
+ hr = Installer_RegistryValueI(curr_user, szKey, 0, szString, VT_BSTR);
ok(hr == S_OK, "Installer_RegistryValueI failed, hresult 0x%08x\n", hr);
ok_w2("Registry name \"%s\" does not match expected \"%s\"\n", szString, szBlank);
/* Get name of a value by positive number (RegEnumValue like), valid index */
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueI(HKEY_CURRENT_USER, szKey, 2, szString, VT_BSTR);
+ hr = Installer_RegistryValueI(curr_user, szKey, 2, szString, VT_BSTR);
ok(hr == S_OK, "Installer_RegistryValueI failed, hresult 0x%08x\n", hr);
/* RegEnumValue order seems different on wine */
todo_wine ok_w2("Registry name \"%s\" does not match expected \"%s\"\n", szString, szTwo);
/* Get name of a value by positive number (RegEnumValue like), invalid index */
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueI(HKEY_CURRENT_USER, szKey, 10, szString, VT_EMPTY);
+ hr = Installer_RegistryValueI(curr_user, szKey, 10, szString, VT_EMPTY);
ok(hr == S_OK, "Installer_RegistryValueI failed, hresult 0x%08x\n", hr);
/* Get name of a subkey by negative number (RegEnumValue like), valid index */
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueI(HKEY_CURRENT_USER, szKey, -1, szString, VT_BSTR);
+ hr = Installer_RegistryValueI(curr_user, szKey, -1, szString, VT_BSTR);
ok(hr == S_OK, "Installer_RegistryValueI failed, hresult 0x%08x\n", hr);
ok_w2("Registry name \"%s\" does not match expected \"%s\"\n", szString, szEight);
/* Get name of a subkey by negative number (RegEnumValue like), invalid index */
memset(szString, 0, sizeof(szString));
- hr = Installer_RegistryValueI(HKEY_CURRENT_USER, szKey, -10, szString, VT_EMPTY);
+ hr = Installer_RegistryValueI(curr_user, szKey, -10, szString, VT_EMPTY);
ok(hr == S_OK, "Installer_RegistryValueI failed, hresult 0x%08x\n", hr);
/* clean up */
@@ -2116,6 +2168,12 @@ static void test_Installer_InstallProduct(void)
/* Installer::InstallProduct */
hr = Installer_InstallProduct(szMsifile, NULL);
+ if (hr == DISP_E_EXCEPTION)
+ {
+ skip("Installer object not supported.\n");
+ delete_test_files();
+ return;
+ }
ok(hr == S_OK, "Installer_InstallProduct failed, hresult 0x%08x\n", hr);
/* Installer::ProductState for our product code, which has been installed */
@@ -2140,14 +2198,14 @@ static void test_Installer_InstallProduct(void)
/* Package name */
memset(szString, 0, sizeof(szString));
hr = Installer_ProductInfo(szProductCode, WINE_INSTALLPROPERTY_PACKAGENAMEW, szString);
- todo_wine ok(hr == S_OK, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
+ ok(hr == S_OK, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
todo_wine ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, szMsifile);
/* Product name */
memset(szString, 0, sizeof(szString));
hr = Installer_ProductInfo(szProductCode, WINE_INSTALLPROPERTY_PRODUCTNAMEW, szString);
ok(hr == S_OK, "Installer_ProductInfo failed, hresult 0x%08x\n", hr);
- ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, szMSITEST);
+ todo_wine ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, szMSITEST);
/* Installer::Products */
test_Installer_Products(TRUE);
diff --git a/rostests/winetests/msi/db.c b/rostests/winetests/msi/db.c
index e912a3a0685..9be169184fa 100644
--- a/rostests/winetests/msi/db.c
+++ b/rostests/winetests/msi/db.c
@@ -1643,17 +1643,18 @@ static void test_msiimport(void)
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = add_table_to_db(hdb, endlines1);
- todo_wine
+ if (r == ERROR_FUNCTION_FAILED)
{
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ /* win9x doesn't handle this case */
+ skip("endlines not handled correctly.\n");
+ MsiCloseHandle(hdb);
+ DeleteFileA(msifile);
+ return;
}
r = add_table_to_db(hdb, endlines2);
- todo_wine
- {
- ok(r == ERROR_FUNCTION_FAILED,
- "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
- }
+ ok(r == ERROR_FUNCTION_FAILED,
+ "Expected ERROR_FUNCTION_FAILED, got %d\n", r);
query = "SELECT * FROM `TestTable`";
r = MsiDatabaseOpenView(hdb, query, &view);
@@ -1752,7 +1753,8 @@ static void test_msiimport(void)
MsiCloseHandle(rec);
r = MsiViewFetch(view, &rec);
- ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
r = MsiViewClose(view);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -1761,37 +1763,28 @@ static void test_msiimport(void)
query = "SELECT * FROM `Table`";
r = MsiDatabaseOpenView(hdb, query, &view);
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- }
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
count = MsiRecordGetFieldCount(rec);
- todo_wine
- {
- ok(count == 6, "Expected 6, got %d\n", count);
- ok(check_record(rec, 1, "A"), "Expected A\n");
- ok(check_record(rec, 2, "B"), "Expected B\n");
- ok(check_record(rec, 3, "C"), "Expected C\n");
- ok(check_record(rec, 4, "D"), "Expected D\n");
- ok(check_record(rec, 5, "E"), "Expected E\n");
- ok(check_record(rec, 6, "F"), "Expected F\n");
- }
+ ok(count == 6, "Expected 6, got %d\n", count);
+ ok(check_record(rec, 1, "A"), "Expected A\n");
+ ok(check_record(rec, 2, "B"), "Expected B\n");
+ ok(check_record(rec, 3, "C"), "Expected C\n");
+ ok(check_record(rec, 4, "D"), "Expected D\n");
+ ok(check_record(rec, 5, "E"), "Expected E\n");
+ ok(check_record(rec, 6, "F"), "Expected F\n");
MsiCloseHandle(rec);
r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
count = MsiRecordGetFieldCount(rec);
- todo_wine
- {
- ok(count == 6, "Expected 6, got %d\n", count);
- ok(check_record(rec, 1, "s72"), "Expected s72\n");
- ok(check_record(rec, 2, "s72"), "Expected s72\n");
- ok(check_record(rec, 3, "s72"), "Expected s72\n");
- ok(check_record(rec, 4, "s72"), "Expected s72\n");
- ok(check_record(rec, 5, "s72"), "Expected s72\n");
- ok(check_record(rec, 6, "s72"), "Expected s72\n");
- }
+ ok(count == 6, "Expected 6, got %d\n", count);
+ ok(check_record(rec, 1, "s72"), "Expected s72\n");
+ ok(check_record(rec, 2, "s72"), "Expected s72\n");
+ ok(check_record(rec, 3, "s72"), "Expected s72\n");
+ ok(check_record(rec, 4, "s72"), "Expected s72\n");
+ ok(check_record(rec, 5, "s72"), "Expected s72\n");
+ ok(check_record(rec, 6, "s72"), "Expected s72\n");
MsiCloseHandle(rec);
MsiViewClose(view);
@@ -1799,51 +1792,36 @@ static void test_msiimport(void)
query = "SELECT * FROM `Table`";
r = MsiDatabaseOpenView(hdb, query, &view);
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- }
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = MsiViewExecute(view, 0);
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- }
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = MsiViewFetch(view, &rec);
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(check_record(rec, 1, "a"), "Expected 'a'\n");
- ok(check_record(rec, 2, "b"), "Expected 'b'\n");
- ok(check_record(rec, 3, "c"), "Expected 'c'\n");
- ok(check_record(rec, 4, "d"), "Expected 'd'\n");
- ok(check_record(rec, 5, "e"), "Expected 'e'\n");
- ok(check_record(rec, 6, "f"), "Expected 'f'\n");
- }
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(check_record(rec, 1, "a"), "Expected 'a'\n");
+ ok(check_record(rec, 2, "b"), "Expected 'b'\n");
+ ok(check_record(rec, 3, "c"), "Expected 'c'\n");
+ ok(check_record(rec, 4, "d"), "Expected 'd'\n");
+ ok(check_record(rec, 5, "e"), "Expected 'e'\n");
+ ok(check_record(rec, 6, "f"), "Expected 'f'\n");
MsiCloseHandle(rec);
r = MsiViewFetch(view, &rec);
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(check_record(rec, 1, "g"), "Expected 'g'\n");
- ok(check_record(rec, 2, "h"), "Expected 'h'\n");
- ok(check_record(rec, 3, "i"), "Expected 'i'\n");
- ok(check_record(rec, 4, "j"), "Expected 'j'\n");
- ok(check_record(rec, 5, "k"), "Expected 'k'\n");
- ok(check_record(rec, 6, "l"), "Expected 'l'\n");
- }
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(check_record(rec, 1, "g"), "Expected 'g'\n");
+ ok(check_record(rec, 2, "h"), "Expected 'h'\n");
+ ok(check_record(rec, 3, "i"), "Expected 'i'\n");
+ ok(check_record(rec, 4, "j"), "Expected 'j'\n");
+ ok(check_record(rec, 5, "k"), "Expected 'k'\n");
+ ok(check_record(rec, 6, "l"), "Expected 'l'\n");
MsiCloseHandle(rec);
r = MsiViewFetch(view, &rec);
- todo_wine
- {
- ok(r == ERROR_NO_MORE_ITEMS,
- "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
- }
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
MsiViewClose(view);
MsiCloseHandle(view);
@@ -3235,6 +3213,11 @@ static void test_join(void)
MsiViewClose(hview);
MsiCloseHandle(hview);
+ query = "SELECT * FROM `Nonexistent`, `One`";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok( r == ERROR_BAD_QUERY_SYNTAX,
+ "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r );
+
MsiCloseHandle(hdb);
DeleteFile(msifile);
}
@@ -4799,6 +4782,10 @@ static void test_order(void)
hdb = create_db();
ok(hdb, "failed to create db\n");
+ query = "CREATE TABLE `Empty` ( `A` SHORT NOT NULL PRIMARY KEY `A`)";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
query = "CREATE TABLE `Mesa` ( `A` SHORT NOT NULL, `B` SHORT, `C` SHORT PRIMARY KEY `A`)";
r = run_query(hdb, 0, query);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -4984,6 +4971,18 @@ static void test_order(void)
r = MsiViewFetch(hview, &hrec);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ MsiViewClose(hview);
+ MsiCloseHandle(hview);
+
+ query = "SELECT * FROM `Empty` ORDER BY `A`";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiViewExecute(hview, 0);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+
MsiViewClose(hview);
MsiCloseHandle(hview);
MsiCloseHandle(hdb);
@@ -5255,10 +5254,7 @@ static void test_quotes(void)
write_file("import.idt", import_dat, (sizeof(import_dat) - 1) * sizeof(char));
r = MsiDatabaseImportA(hdb, CURR_DIR, "import.idt");
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- }
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
DeleteFileA("import.idt");
@@ -5275,19 +5271,13 @@ static void test_quotes(void)
size = MAX_PATH;
r = MsiRecordGetString(hrec, 1, buf, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- todo_wine
- {
- ok(!lstrcmp(buf, "This is a new 'string' ok"),
- "Expected \"This is a new 'string' ok\", got %s\n", buf);
- }
+ ok(!lstrcmp(buf, "This is a new 'string' ok"),
+ "Expected \"This is a new 'string' ok\", got %s\n", buf);
MsiCloseHandle(hrec);
r = MsiViewFetch(hview, &hrec);
- todo_wine
- {
- ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
- }
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
MsiCloseHandle(hview);
@@ -5501,6 +5491,360 @@ static void test_carriagereturn(void)
DeleteFileA(msifile);
}
+static void test_noquotes(void)
+{
+ MSIHANDLE hdb, hview, hrec;
+ const char *query;
+ char buf[MAX_PATH];
+ UINT r;
+ DWORD size;
+
+ DeleteFile(msifile);
+
+ r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "CREATE TABLE Table ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ query = "CREATE TABLE `Table` ( A CHAR(72) NOT NULL PRIMARY KEY `A` )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "CREATE TABLE `Table2` ( `A` CHAR(72) NOT NULL PRIMARY KEY A )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "CREATE TABLE `Table3` ( A CHAR(72) NOT NULL PRIMARY KEY A )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "SELECT * FROM `_Tables`";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiViewExecute(hview, 0);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
+
+ MsiCloseHandle(hrec);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf);
+
+ MsiCloseHandle(hrec);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf);
+
+ MsiCloseHandle(hrec);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+
+ MsiViewClose(hview);
+ MsiCloseHandle(hview);
+
+ query = "SELECT * FROM `_Columns`";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiViewExecute(hview, 0);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "Table"), "Expected \"Table\", got \"%s\"\n", buf);
+
+ r = MsiRecordGetInteger(hrec, 2);
+ ok(r == 1, "Expected 1, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 3, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
+
+ MsiCloseHandle(hrec);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "Table2"), "Expected \"Table2\", got \"%s\"\n", buf);
+
+ r = MsiRecordGetInteger(hrec, 2);
+ ok(r == 1, "Expected 1, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 3, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
+
+ MsiCloseHandle(hrec);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "Table3"), "Expected \"Table3\", got \"%s\"\n", buf);
+
+ r = MsiRecordGetInteger(hrec, 2);
+ ok(r == 1, "Expected 1, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 3, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "A"), "Expected \"A\", got \"%s\"\n", buf);
+
+ MsiCloseHandle(hrec);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+
+ MsiViewClose(hview);
+ MsiCloseHandle(hview);
+
+ query = "INSERT INTO Table ( `A` ) VALUES ( 'hi' )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ query = "INSERT INTO `Table` ( A ) VALUES ( 'hi' )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "INSERT INTO `Table` ( `A` ) VALUES ( hi )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ query = "SELECT * FROM Table WHERE `A` = 'hi'";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ query = "SELECT * FROM `Table` WHERE `A` = hi";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ query = "SELECT * FROM Table";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ query = "SELECT * FROM Table2";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiViewExecute(hview, 0);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+
+ MsiViewClose(hview);
+ MsiCloseHandle(hview);
+
+ query = "SELECT * FROM `Table` WHERE A = 'hi'";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiViewExecute(hview, 0);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buf, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "hi"), "Expected \"hi\", got \"%s\"\n", buf);
+
+ MsiCloseHandle(hrec);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+
+ MsiViewClose(hview);
+ MsiCloseHandle(hview);
+
+
+ MsiCloseHandle(hdb);
+ DeleteFileA(msifile);
+}
+
+static void read_file_data(LPCSTR filename, LPSTR buffer)
+{
+ OFSTRUCT ofs;
+ HFILE file;
+ DWORD read;
+
+ file = OpenFile(filename, &ofs, OF_READ);
+ ZeroMemory(buffer, MAX_PATH);
+ ReadFile((HANDLE)file, buffer, MAX_PATH, &read, NULL);
+ CloseHandle((HANDLE)file);
+}
+
+static void test_forcecodepage(void)
+{
+ MSIHANDLE hdb;
+ const char *query;
+ char buffer[MAX_PATH];
+ UINT r;
+
+ DeleteFile(msifile);
+
+ r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "SELECT * FROM `_ForceCodepage`";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL PRIMARY KEY `A` )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "SELECT * FROM `_ForceCodepage`";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ r = MsiDatabaseCommit(hdb);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "SELECT * FROM `_ForceCodepage`";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ MsiCloseHandle(hdb);
+
+ r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "SELECT * FROM `_ForceCodepage`";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
+
+ r = MsiDatabaseExport(hdb, "_ForceCodepage", CURR_DIR, "forcecodepage.idt");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ read_file_data("forcecodepage.idt", buffer);
+ ok(!lstrcmpA(buffer, "\r\n\r\n0\t_ForceCodepage\r\n"),
+ "Expected \"\r\n\r\n0\t_ForceCodepage\r\n\", got \"%s\"", buffer);
+
+ MsiCloseHandle(hdb);
+ DeleteFileA(msifile);
+ DeleteFileA("forcecodepage.idt");
+}
+
+static void test_viewmodify_refresh(void)
+{
+ MSIHANDLE hdb, hview, hrec;
+ const char *query;
+ char buffer[MAX_PATH];
+ UINT r;
+ DWORD size;
+
+ DeleteFile(msifile);
+
+ r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "CREATE TABLE `Table` ( `A` CHAR(72) NOT NULL, `B` INT PRIMARY KEY `A` )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hi', 1 )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "SELECT * FROM `Table`";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiViewExecute(hview, 0);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hi'";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buffer, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buffer, "hi"), "Expected \"hi\", got \"%s\"\n", buffer);
+ ok(size == 2, "Expected 2, got %d\n", size);
+
+ r = MsiRecordGetInteger(hrec, 2);
+ ok(r == 2, "Expected 2, got %d\n", r);
+
+ MsiCloseHandle(hrec);
+ MsiViewClose(hview);
+ MsiCloseHandle(hview);
+
+ query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hello', 3 )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "SELECT * FROM `Table` WHERE `B` = 3";
+ r = MsiDatabaseOpenView(hdb, query, &hview);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiViewExecute(hview, 0);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewFetch(hview, &hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "UPDATE `Table` SET `B` = 2 WHERE `A` = 'hello'";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ query = "INSERT INTO `Table` ( `A`, `B` ) VALUES ( 'hithere', 3 )";
+ r = run_query(hdb, 0, query);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ r = MsiViewModify(hview, MSIMODIFY_REFRESH, hrec);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ size = MAX_PATH;
+ r = MsiRecordGetStringA(hrec, 1, buffer, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buffer, "hello"), "Expected \"hello\", got \"%s\"\n", buffer);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ r = MsiRecordGetInteger(hrec, 2);
+ ok(r == 2, "Expected 2, got %d\n", r);
+
+ MsiCloseHandle(hrec);
+ MsiViewClose(hview);
+ MsiCloseHandle(hview);
+ MsiCloseHandle(hdb);
+ DeleteFileA(msifile);
+}
+
START_TEST(db)
{
test_msidatabase();
@@ -5534,4 +5878,7 @@ START_TEST(db)
test_deleterow();
test_quotes();
test_carriagereturn();
+ test_noquotes();
+ test_forcecodepage();
+ test_viewmodify_refresh();
}
diff --git a/rostests/winetests/msi/format.c b/rostests/winetests/msi/format.c
index aec347dad73..f4c1670cf4a 100644
--- a/rostests/winetests/msi/format.c
+++ b/rostests/winetests/msi/format.c
@@ -21,6 +21,7 @@
#include
#include
+#include
#include
#include
@@ -2176,6 +2177,7 @@ static void test_formatrecord_tables(void)
CHAR buf[MAX_PATH];
CHAR curr_dir[MAX_PATH];
CHAR expected[MAX_PATH];
+ CHAR root[MAX_PATH];
DWORD size;
UINT r;
@@ -2304,48 +2306,57 @@ static void test_formatrecord_tables(void)
r = MsiDoAction(hpkg, "CostFinalize");
ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
+ size = MAX_PATH;
+ MsiGetProperty( hpkg, "ROOTDRIVE", root, &size );
+
+ sprintf( expected, "1: %sfrontal.txt ", root);
+
/* frontal full file key */
size = MAX_PATH;
MsiRecordSetString( hrec, 1, "[#frontal_file]" );
r = MsiFormatRecord( hpkg, hrec, buf, &size );
ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
- ok( !lstrcmp( buf, "1: C:\\frontal.txt " ), "Expected '1: C:\\frontal.txt ', got %s\n", buf);
+ ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
/* frontal short file key */
size = MAX_PATH;
MsiRecordSetString( hrec, 1, "[!frontal_file]" );
r = MsiFormatRecord( hpkg, hrec, buf, &size );
ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
- ok( !lstrcmp( buf, "1: C:\\frontal.txt " ), "Expected '1: C:\\frontal.txt ', got %s\n", buf);
+ ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
+
+ sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
/* temporal full file key */
size = MAX_PATH;
MsiRecordSetString( hrec, 1, "[#temporal_file]" );
r = MsiFormatRecord( hpkg, hrec, buf, &size );
ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
- ok( !lstrcmp( buf, "1: C:\\I am a really long directory\\temporal.txt " ),
- "Expected '1: C:\\I am a really long directory\\temporal.txt ', got %s\n", buf);
+ ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
/* temporal short file key */
size = MAX_PATH;
MsiRecordSetString( hrec, 1, "[!temporal_file]" );
r = MsiFormatRecord( hpkg, hrec, buf, &size );
ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
- ok( !lstrcmp( buf, "1: C:\\I am a really long directory\\temporal.txt " ),
- "Expected '1: C:\\I am a really long directory\\temporal.txt ', got %s\n", buf);
+ ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
/* custom action 51, files don't exist */
r = MsiDoAction( hpkg, "MyCustom" );
ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
+ sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
+
size = MAX_PATH;
r = MsiGetProperty( hpkg, "prop", buf, &size );
ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
- ok( !lstrcmp( buf, "C:\\I am a really long directory\\temporal.txt" ),
- "Expected 'C:\\I am a really long directory\\temporal.txt', got %s\n", buf);
+ ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
- CreateDirectory( "C:\\I am a really long directory", NULL );
- create_test_file( "C:\\I am a really long directory\\temporal.txt" );
+ sprintf( buf, "%sI am a really long directory", root );
+ CreateDirectory( buf, NULL );
+
+ lstrcat( buf, "\\temporal.txt" );
+ create_test_file( buf );
/* custom action 51, files exist */
r = MsiDoAction( hpkg, "MyCustom" );
@@ -2356,8 +2367,7 @@ static void test_formatrecord_tables(void)
ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
todo_wine
{
- ok( !lstrcmp( buf, "C:\\I am a really long directory\\temporal.txt" ),
- "Expected 'C:\\I am a really long directory\\temporal.txt', got %s\n", buf);
+ ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
}
/* custom action 51, escaped text 1 */
@@ -2387,13 +2397,14 @@ static void test_formatrecord_tables(void)
ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
ok( !lstrcmp( buf, "" ), "Expected '', got %s\n", buf);
+ sprintf( expected, "1: %sI am a really long directory\\ ", root);
+
/* component with INSTALLSTATE_LOCAL */
size = MAX_PATH;
MsiRecordSetString( hrec, 1, "[$temporal]" );
r = MsiFormatRecord( hpkg, hrec, buf, &size );
ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
- ok( !lstrcmp( buf, "1: C:\\I am a really long directory\\ " ),
- "Expected '1: C:\\I am a really long directory\\ ', got %s\n", buf);
+ ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
r = MsiSetComponentState( hpkg, "temporal", INSTALLSTATE_SOURCE );
ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
@@ -2408,8 +2419,11 @@ static void test_formatrecord_tables(void)
ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
ok( !lstrcmp( buf, expected ), "Expected '%s', got %s\n", expected, buf);
- DeleteFile( "C:\\I am a really long directory\\temporal.txt" );
- RemoveDirectory( "C:\\I am a really long directory" );
+ sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
+ DeleteFile( buf );
+
+ sprintf( buf, "%sI am a really long directory", root );
+ RemoveDirectory( buf );
MsiCloseHandle( hrec );
MsiCloseHandle( hpkg );
diff --git a/rostests/winetests/msi/install.c b/rostests/winetests/msi/install.c
index b5892c0880e..5ac3852416b 100644
--- a/rostests/winetests/msi/install.c
+++ b/rostests/winetests/msi/install.c
@@ -34,6 +34,8 @@
static UINT (WINAPI *pMsiQueryComponentStateA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
+static UINT (WINAPI *pMsiSourceListEnumSourcesA)
+ (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
static UINT (WINAPI *pMsiSourceListGetInfoA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
@@ -144,7 +146,9 @@ static const CHAR property_dat[] = "Property\tValue\n"
"Setup\tSetup\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
- "ROOTDRIVE\tC:\\\n";
+ "ROOTDRIVE\tC:\\\n"
+ "SERVNAME\tTestService\n"
+ "SERVDISP\tTestServiceDisp\n";
static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
"s72\ti2\tl255\tL255\tL0\ts72\n"
@@ -158,7 +162,7 @@ static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tSe
"LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
"s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
"ServiceInstall\tServiceInstall\n"
- "TestService\tTestService\tTestService\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
+ "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
"s72\tl255\ti2\tL255\tI2\ts72\n"
@@ -173,6 +177,13 @@ static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttr
"augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
"caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
+static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
+ "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
+ "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
+
static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
"s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
"Feature\tFeature\n"
@@ -192,6 +203,14 @@ static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion
"augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
"caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
+static const CHAR cc2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+ "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+ "File\tFile\n"
+ "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
+ "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
+ "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
+ "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
+
static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
"i2\ti4\tL64\tS255\tS32\tS72\n"
"Media\tDiskId\n"
@@ -352,7 +371,7 @@ static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
"s72\ti2\tS64\tS0\tS255\n"
"CustomAction\tAction\n"
- "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
+ "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
"s72\tS38\ts72\ti2\tS255\tS72\n"
@@ -586,6 +605,31 @@ static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tCompon
"Registry\tRegistry\n"
"regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
+static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "augustus\t\tMSITESTDIR\t0\tMYPROP=42\taugustus\n";
+
+static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "ValidateProductID\t\t700\n"
+ "GoodSetProperty\t\t725\n"
+ "BadSetProperty\t\t750\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "InstallFiles\t\t4000\n"
+ "InstallFinalize\t\t6600";
+
+static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
+ "s72\ti2\tS64\tS0\n"
+ "CustomAction\tAction\n"
+ "GoodSetProperty\t51\tMYPROP\t42\n"
+ "BadSetProperty\t51\t\tMYPROP\n";
+
typedef struct _msi_table
{
const CHAR *filename;
@@ -622,6 +666,18 @@ static const msi_table cc_tables[] =
ADD_TABLE(property),
};
+static const msi_table cc2_tables[] =
+{
+ ADD_TABLE(cc2_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(cc_feature),
+ ADD_TABLE(cc_feature_comp),
+ ADD_TABLE(cc2_file),
+ ADD_TABLE(install_exec_seq),
+ ADD_TABLE(cc_media),
+ ADD_TABLE(property),
+};
+
static const msi_table co_tables[] =
{
ADD_TABLE(cc_component),
@@ -887,6 +943,31 @@ static const msi_table wrv_tables[] =
ADD_TABLE(wrv_registry),
};
+static const msi_table sf_tables[] =
+{
+ ADD_TABLE(wrv_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(rof_feature),
+ ADD_TABLE(ci2_feature_comp),
+ ADD_TABLE(ci2_file),
+ ADD_TABLE(install_exec_seq),
+ ADD_TABLE(rof_media),
+ ADD_TABLE(property),
+};
+
+static const msi_table ca51_tables[] =
+{
+ ADD_TABLE(ca51_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(rof_feature),
+ ADD_TABLE(ci2_feature_comp),
+ ADD_TABLE(ci2_file),
+ ADD_TABLE(ca51_install_exec_seq),
+ ADD_TABLE(rof_media),
+ ADD_TABLE(property),
+ ADD_TABLE(ca51_custom_action),
+};
+
/* cabinet definitions */
/* make the max size large so there is only one cab file */
@@ -1007,6 +1088,7 @@ static void init_functionpointers(void)
trace("GetProcAddress(%s) failed\n", #func);
GET_PROC(MsiQueryComponentStateA);
+ GET_PROC(MsiSourceListEnumSourcesA);
GET_PROC(MsiSourceListGetInfoA);
#undef GET_PROC
@@ -1331,6 +1413,15 @@ static void test_MsiInstallProduct(void)
LONG res;
HKEY hkey;
DWORD num, size, type;
+ SC_HANDLE scm;
+
+ scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
+ if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
+ {
+ skip("Services are not implemented, we are most likely on win9x\n");
+ return;
+ }
+ CloseServiceHandle(scm);
create_test_files();
create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
@@ -1486,21 +1577,25 @@ static void create_cc_test_files(void)
create_file("maximus", 500);
create_file("augustus", 50000);
+ create_file("tiberius", 500);
create_file("caesar", 500);
- set_cab_parameters(&cabParams, "test1.cab", 200);
+ set_cab_parameters(&cabParams, "test1.cab", 40000);
hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
fci_read, fci_write, fci_close, fci_seek, fci_delete,
get_temp_file, &cabParams, cab_context);
ok(hfci != NULL, "Failed to create an FCI context\n");
- res = add_file(hfci, "maximus", tcompTYPE_MSZIP);
+ res = add_file(hfci, "maximus", tcompTYPE_NONE);
ok(res, "Failed to add file maximus\n");
- res = add_file(hfci, "augustus", tcompTYPE_MSZIP);
+ res = add_file(hfci, "augustus", tcompTYPE_NONE);
ok(res, "Failed to add file augustus\n");
+ res = add_file(hfci, "tiberius", tcompTYPE_NONE);
+ ok(res, "Failed to add file tiberius\n");
+
res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
ok(res, "Failed to flush the cabinet\n");
@@ -1511,6 +1606,7 @@ static void create_cc_test_files(void)
DeleteFile("maximus");
DeleteFile("augustus");
+ DeleteFile("tiberius");
DeleteFile("caesar");
}
@@ -1542,13 +1638,29 @@ static void test_continuouscabs(void)
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
r = MsiInstallProductA(msifile, NULL);
- ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
- todo_wine
+ if (r == ERROR_SUCCESS) /* win9x has a problem with this */
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
}
+
+ delete_cab_files();
+ DeleteFile(msifile);
+
+ create_cc_test_files();
+ create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
+ ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
+ ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "File not installed\n");
delete_cab_files();
@@ -1605,13 +1717,13 @@ static void test_caborder(void)
create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
r = MsiInstallProductA(msifile, NULL);
- ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
ok(!delete_pf("msitest", FALSE), "File is installed\n");
todo_wine
{
+ ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
- ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
}
delete_cab_files();
@@ -1621,11 +1733,11 @@ static void test_caborder(void)
create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
r = MsiInstallProductA(msifile, NULL);
- ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
todo_wine
{
ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+ ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
ok(!delete_pf("msitest", FALSE), "File is installed\n");
}
@@ -1679,14 +1791,14 @@ static void test_samesequence(void)
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
r = MsiInstallProductA(msifile, NULL);
- todo_wine
+ if (r == ERROR_SUCCESS) /* win9x has a problem with this */
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
}
- ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
- ok(delete_pf("msitest", FALSE), "File not installed\n");
delete_cab_files();
DeleteFile(msifile);
@@ -1702,14 +1814,14 @@ static void test_uiLevelFlags(void)
MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
r = MsiInstallProductA(msifile, NULL);
- ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
- todo_wine
+ if (r == ERROR_SUCCESS) /* win9x has a problem with this */
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
}
- ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
- ok(delete_pf("msitest", FALSE), "File not installed\n");
delete_cab_files();
DeleteFile(msifile);
@@ -1848,9 +1960,15 @@ static void test_concurrentinstall(void)
ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "File not installed\n");
- /* Delete the files in the temp (current) folder */
- DeleteFile(msifile);
DeleteFile(path);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
+ ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+ DeleteFile(msifile);
DeleteFile("msitest\\msitest\\augustus");
DeleteFile("msitest\\maximus");
RemoveDirectory("msitest\\msitest");
@@ -1980,6 +2098,721 @@ static void get_date_str(LPSTR date)
sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
}
+static void test_publish_registerproduct(void)
+{
+ UINT r;
+ LONG res;
+ HKEY uninstall, prodkey;
+ INSTALLSTATE state;
+ CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+ char date[MAX_PATH];
+ char temp[MAX_PATH];
+
+ static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+
+ if (!pMsiQueryComponentStateA)
+ {
+ skip("MsiQueryComponentStateA is not available\n");
+ return;
+ }
+
+ get_date_str(date);
+ GetTempPath(MAX_PATH, temp);
+
+ res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\maximus", 500);
+
+ create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* RegisterProduct */
+ r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
+ CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
+ CHECK_REG_STR(prodkey, "InstallDate", date);
+ CHECK_REG_STR(prodkey, "InstallSource", temp);
+ CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ CHECK_REG_STR(prodkey, "Publisher", "Wine");
+ CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
+ CHECK_REG_STR(prodkey, "Comments", NULL);
+ CHECK_REG_STR(prodkey, "Contact", NULL);
+ CHECK_REG_STR(prodkey, "HelpLink", NULL);
+ CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
+ CHECK_REG_STR(prodkey, "InstallLocation", NULL);
+ CHECK_REG_STR(prodkey, "Readme", NULL);
+ CHECK_REG_STR(prodkey, "Size", NULL);
+ CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
+ CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
+ CHECK_REG_DWORD(prodkey, "Language", 1033);
+ CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
+ CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
+ CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
+ CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
+ todo_wine
+ {
+ CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
+ }
+
+ RegCloseKey(prodkey);
+
+ /* try to uninstall after RegisterProduct */
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ }
+ ok(pf_exists("msitest\\maximus"), "File deleted\n");
+ ok(pf_exists("msitest"), "File deleted\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ todo_wine
+ {
+ ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
+ }
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+ }
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ todo_wine
+ {
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ }
+
+ todo_wine
+ {
+ CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
+ CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
+ CHECK_REG_STR(prodkey, "InstallDate", date);
+ CHECK_REG_STR(prodkey, "InstallSource", temp);
+ CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ CHECK_REG_STR(prodkey, "Publisher", "Wine");
+ CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
+ CHECK_REG_STR(prodkey, "Comments", NULL);
+ CHECK_REG_STR(prodkey, "Contact", NULL);
+ CHECK_REG_STR(prodkey, "HelpLink", NULL);
+ CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
+ CHECK_REG_STR(prodkey, "InstallLocation", NULL);
+ CHECK_REG_STR(prodkey, "Readme", NULL);
+ CHECK_REG_STR(prodkey, "Size", NULL);
+ CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
+ CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
+ CHECK_REG_DWORD(prodkey, "Language", 1033);
+ CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
+ CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
+ CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
+ CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
+ CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
+ }
+
+ RegCloseKey(prodkey);
+
+ /* full install to remove */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ RegCloseKey(uninstall);
+ DeleteFile(msifile);
+ DeleteFile("msitest\\maximus");
+ RemoveDirectory("msitest");
+ delete_pfmsitest_files();
+}
+
+static void test_publish_publishproduct(void)
+{
+ UINT r;
+ LONG res;
+ HKEY uninstall, prodkey;
+ INSTALLSTATE state;
+ CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+
+ static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+
+ if (!pMsiQueryComponentStateA)
+ {
+ skip("MsiQueryComponentStateA is not available\n");
+ return;
+ }
+
+ res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\maximus", 500);
+
+ create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* PublishProduct */
+ r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* try to uninstall after PublishProduct */
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File deleted\n");
+ ok(pf_exists("msitest"), "File deleted\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* full install to remove */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ RegCloseKey(uninstall);
+ DeleteFile(msifile);
+ DeleteFile("msitest\\maximus");
+ RemoveDirectory("msitest");
+ delete_pfmsitest_files();
+}
+
+static void test_publish_publishfeatures(void)
+{
+ UINT r;
+ LONG res;
+ HKEY uninstall, prodkey;
+ INSTALLSTATE state;
+ CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+
+ static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+
+ if (!pMsiQueryComponentStateA)
+ {
+ skip("MsiQueryComponentStateA is not available\n");
+ return;
+ }
+
+ res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\maximus", 500);
+
+ create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* PublishFeatures */
+ r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ /* try to uninstall after PublishFeatures */
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ }
+ ok(pf_exists("msitest\\maximus"), "File deleted\n");
+ ok(pf_exists("msitest"), "File deleted\n");
+
+ /* PublishFeatures and PublishProduct */
+ r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 PUBLISH_FEATURES=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ /* PublishFeatures and RegisterProduct */
+ r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_FEATURES=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ /* full install to remove */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ RegCloseKey(uninstall);
+ DeleteFile(msifile);
+ DeleteFile("msitest\\maximus");
+ RemoveDirectory("msitest");
+ delete_pfmsitest_files();
+}
+
+static void test_publish_registeruser(void)
+{
+ UINT r;
+ LONG res;
+ HKEY uninstall, prodkey;
+ INSTALLSTATE state;
+ CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+
+ static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+
+ if (!pMsiQueryComponentStateA)
+ {
+ skip("MsiQueryComponentStateA is not available\n");
+ return;
+ }
+
+ res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\maximus", 500);
+
+ create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* RegisterUser */
+ r = MsiInstallProductA(msifile, "REGISTER_USER=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* try to uninstall after RegisterUser */
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ }
+ ok(pf_exists("msitest\\maximus"), "File deleted\n");
+ ok(pf_exists("msitest"), "File deleted\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* full install to remove */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ RegCloseKey(uninstall);
+ DeleteFile(msifile);
+ DeleteFile("msitest\\maximus");
+ RemoveDirectory("msitest");
+ delete_pfmsitest_files();
+}
+
+static void get_user_sid(LPSTR *usersid)
+{
+ HANDLE token;
+ BYTE buf[1024];
+ DWORD size;
+ PTOKEN_USER user;
+ HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
+ static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
+
+ *usersid = NULL;
+ pConvertSidToStringSidA = (void *)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
+ if (!pConvertSidToStringSidA)
+ return;
+
+ OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
+ size = sizeof(buf);
+ GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
+ user = (PTOKEN_USER)buf;
+ pConvertSidToStringSidA(user->User.Sid, usersid);
+}
+
+static void test_publish_processcomponents(void)
+{
+ UINT r;
+ LONG res;
+ HKEY uninstall, prodkey, comp;
+ INSTALLSTATE state;
+ LPSTR usersid;
+ CHAR keypath[MAX_PATH];
+ CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+
+ static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+
+ if (!pMsiQueryComponentStateA)
+ {
+ skip("MsiQueryComponentStateA is not available\n");
+ return;
+ }
+
+ get_user_sid(&usersid);
+ if (!usersid)
+ {
+ skip("ConvertSidToStringSidA is not available\n");
+ return;
+ }
+
+ res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\maximus", 500);
+
+ create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* ProcessComponent */
+ r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* try to uninstall after ProcessComponents */
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ }
+ ok(pf_exists("msitest\\maximus"), "File deleted\n");
+ ok(pf_exists("msitest"), "File deleted\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ res = RegOpenKeyA(uninstall, prodcode, &prodkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ /* ProcessComponent with PublishProduct */
+ r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ /* uninstall */
+ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* ProcessComponent with RegisterProduct */
+ r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PROCESS_COMPONENTS=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+
+ /* ProcessComponent with RegisterProduct and PublishProduct */
+ r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(pf_exists("msitest\\maximus"), "File not installed\n");
+ ok(pf_exists("msitest"), "File not installed\n");
+
+ state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
+ ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+
+ r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+
+ /* uninstall */
+ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5");
+
+ /* native has trouble removing the comp key unless it's a full install */
+ res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
+ if (res == ERROR_SUCCESS)
+ {
+ RegDeleteKeyA(comp, "");
+ RegCloseKey(comp);
+ }
+
+ RegCloseKey(uninstall);
+ DeleteFile(msifile);
+ DeleteFile("msitest\\maximus");
+ RemoveDirectory("msitest");
+ delete_pfmsitest_files();
+}
+
static void test_publish(void)
{
UINT r;
@@ -1992,6 +2825,12 @@ static void test_publish(void)
static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+ if (!pMsiQueryComponentStateA)
+ {
+ skip("MsiQueryComponentStateA is not available\n");
+ return;
+ }
+
get_date_str(date);
GetTempPath(MAX_PATH, temp);
@@ -2045,208 +2884,6 @@ static void test_publish(void)
res = RegOpenKeyA(uninstall, prodcode, &prodkey);
ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
- /* install again */
- r = MsiInstallProductA(msifile, NULL);
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(pf_exists("msitest\\maximus"), "File not installed\n");
- ok(pf_exists("msitest"), "File not installed\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
-
- /* try to uninstall */
- r = MsiInstallProductA(msifile, "REMOVE=ALL");
- todo_wine
- {
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- }
- ok(pf_exists("msitest\\maximus"), "File deleted\n");
- ok(pf_exists("msitest"), "File deleted\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
-
- /* PublishProduct */
- r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(pf_exists("msitest\\maximus"), "File not installed\n");
- ok(pf_exists("msitest"), "File not installed\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
-
- /* try to uninstall after PublishProduct */
- r = MsiInstallProductA(msifile, "REMOVE=ALL");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(pf_exists("msitest\\maximus"), "File deleted\n");
- ok(pf_exists("msitest"), "File deleted\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
-
- /* RegisterProduct */
- r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(pf_exists("msitest\\maximus"), "File not installed\n");
- ok(pf_exists("msitest"), "File not installed\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
-
- CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
- CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
- CHECK_REG_STR(prodkey, "InstallDate", date);
- CHECK_REG_STR(prodkey, "InstallSource", temp);
- CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "Publisher", "Wine");
- CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
- CHECK_REG_STR(prodkey, "Comments", NULL);
- CHECK_REG_STR(prodkey, "Contact", NULL);
- CHECK_REG_STR(prodkey, "HelpLink", NULL);
- CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
- CHECK_REG_STR(prodkey, "InstallLocation", NULL);
- CHECK_REG_STR(prodkey, "Readme", NULL);
- CHECK_REG_STR(prodkey, "Size", NULL);
- CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
- CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
- CHECK_REG_DWORD(prodkey, "Language", 1033);
- CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
- CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
- CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
- CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
- todo_wine
- {
- CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
- }
-
- RegCloseKey(prodkey);
-
- /* complete uninstall */
- r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
- todo_wine
- {
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- }
- ok(pf_exists("msitest\\maximus"), "File deleted\n");
- ok(pf_exists("msitest"), "File deleted\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- todo_wine
- {
- ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
- }
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- todo_wine
- {
- ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
- }
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
-
- todo_wine
- {
- CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
- CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
- CHECK_REG_STR(prodkey, "InstallDate", date);
- CHECK_REG_STR(prodkey, "InstallSource", temp);
- CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "Publisher", "Wine");
- CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
- CHECK_REG_STR(prodkey, "Comments", NULL);
- CHECK_REG_STR(prodkey, "Contact", NULL);
- CHECK_REG_STR(prodkey, "HelpLink", NULL);
- CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
- CHECK_REG_STR(prodkey, "InstallLocation", NULL);
- CHECK_REG_STR(prodkey, "Readme", NULL);
- CHECK_REG_STR(prodkey, "Size", NULL);
- CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
- CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
- CHECK_REG_DWORD(prodkey, "Language", 1033);
- CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
- CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
- CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
- CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
- CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
- }
-
- RegCloseKey(prodkey);
-
/* PublishProduct and RegisterProduct */
r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -2299,117 +2936,6 @@ static void test_publish(void)
RegCloseKey(prodkey);
- /* try it again */
- r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(pf_exists("msitest\\maximus"), "File not installed\n");
- ok(pf_exists("msitest"), "File not installed\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- todo_wine
- {
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
- }
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- todo_wine
- {
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- }
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- todo_wine
- {
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
- }
-
- /* uninstall has a problem with this */
- r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
- todo_wine
- {
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- }
- ok(pf_exists("msitest\\maximus"), "File deleted\n");
- ok(pf_exists("msitest"), "File deleted\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- todo_wine
- {
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
- }
-
- /* PublishProduct and RegisterProduct and ProcessComponents */
- r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(pf_exists("msitest\\maximus"), "File not installed\n");
- ok(pf_exists("msitest"), "File not installed\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
-
- CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
- CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
- CHECK_REG_STR(prodkey, "InstallDate", date);
- CHECK_REG_STR(prodkey, "InstallSource", temp);
- CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "Publisher", "Wine");
- CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
- CHECK_REG_STR(prodkey, "Comments", NULL);
- CHECK_REG_STR(prodkey, "Contact", NULL);
- CHECK_REG_STR(prodkey, "HelpLink", NULL);
- CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
- CHECK_REG_STR(prodkey, "InstallLocation", NULL);
- CHECK_REG_STR(prodkey, "Readme", NULL);
- CHECK_REG_STR(prodkey, "Size", NULL);
- CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
- CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
- CHECK_REG_DWORD(prodkey, "Language", 1033);
- CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
- CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
- CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
- CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
- todo_wine
- {
- CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
- }
-
- RegCloseKey(prodkey);
-
- /* complete uninstall */
r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(pf_exists("msitest\\maximus"), "File deleted\n");
@@ -2430,91 +2956,7 @@ static void test_publish(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- todo_wine
- {
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
- }
-
- /* PublishProduct, RegisterProduct, ProcessComponents, PublishFeatures */
- r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1 PUBLISH_FEATURES=1");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(pf_exists("msitest\\maximus"), "File not installed\n");
- ok(pf_exists("msitest"), "File not installed\n");
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
-
- CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
- CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
- CHECK_REG_STR(prodkey, "InstallDate", date);
- CHECK_REG_STR(prodkey, "InstallSource", temp);
- CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "Publisher", "Wine");
- CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
- CHECK_REG_STR(prodkey, "Comments", NULL);
- CHECK_REG_STR(prodkey, "Contact", NULL);
- CHECK_REG_STR(prodkey, "HelpLink", NULL);
- CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
- CHECK_REG_STR(prodkey, "InstallLocation", NULL);
- CHECK_REG_STR(prodkey, "Readme", NULL);
- CHECK_REG_STR(prodkey, "Size", NULL);
- CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
- CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
- CHECK_REG_DWORD(prodkey, "Language", 1033);
- CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
- CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
- CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
- CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
- todo_wine
- {
- CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
- }
-
- RegCloseKey(prodkey);
-
- /* complete uninstall */
- r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- todo_wine
- {
- ok(!pf_exists("msitest\\maximus"), "File deleted\n");
- ok(!pf_exists("msitest"), "File deleted\n");
- }
-
- state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
- ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
- res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- todo_wine
- {
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
- }
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
/* complete install */
r = MsiInstallProductA(msifile, "FULL=1");
@@ -2852,10 +3294,7 @@ static void test_publish(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
res = RegOpenKeyA(uninstall, prodcode, &prodkey);
- todo_wine
- {
- ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
- }
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
/* make sure 'Program Files\msitest' is removed */
delete_pfmsitest_files();
@@ -2871,8 +3310,15 @@ static void test_publishsourcelist(void)
UINT r;
DWORD size;
CHAR value[MAX_PATH];
+ CHAR path[MAX_PATH];
CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+ if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
+ {
+ skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
+ return;
+ }
+
CreateDirectoryA("msitest", NULL);
create_file("msitest\\maximus", 500);
@@ -2888,7 +3334,13 @@ static void test_publishsourcelist(void)
/* nothing published */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
@@ -2900,7 +3352,13 @@ static void test_publishsourcelist(void)
/* after RegisterProduct */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
@@ -2912,7 +3370,13 @@ static void test_publishsourcelist(void)
/* after ProcessComponents */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
@@ -2924,7 +3388,13 @@ static void test_publishsourcelist(void)
/* after PublishFeatures */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
@@ -2937,13 +3407,69 @@ static void test_publishsourcelist(void)
size = MAX_PATH;
lstrcpyA(value, "aaa");
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
- ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
- ok(size == 11, "Expected 11, got %d\n", size);
- }
+ MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
+ ok(size == 11, "Expected 11, got %d\n", size);
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
+ ok(size == 0, "Expected 0, got %d\n", size);
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
+ ok(size == 0, "Expected 0, got %d\n", size);
+
+ lstrcpyA(path, CURR_DIR);
+ lstrcatA(path, "\\");
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
+ ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
+ ok(size == 1, "Expected 1, got %d\n", size);
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
+ ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
/* complete uninstall */
r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
@@ -3530,12 +4056,18 @@ static void test_movefiles(void)
ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
- ok(!delete_pf("msitest\\apple", TRUE), "File should not exist\n");
+ /* either apple or application will be moved depending on directory order */
+ if (!delete_pf("msitest\\apple", TRUE))
+ ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
+ else
+ ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
- ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
- ok(delete_pf("msitest\\foo", TRUE), "File not moved\n");
- ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
+ /* either fao or foo will be moved depending on directory order */
+ if (delete_pf("msitest\\foo", TRUE))
+ ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
+ else
+ ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
@@ -3685,6 +4217,62 @@ static void test_writeregistryvalues(void)
RemoveDirectory("msitest");
}
+static void test_sourcefolder(void)
+{
+ UINT r;
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("augustus", 500);
+
+ create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
+ todo_wine
+ {
+ ok(r == ERROR_INSTALL_FAILURE,
+ "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+ ok(!delete_pf("msitest", FALSE), "File installed\n");
+ }
+
+ RemoveDirectoryA("msitest");
+
+ r = MsiInstallProductA(msifile, NULL);
+ todo_wine
+ {
+ ok(r == ERROR_INSTALL_FAILURE,
+ "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+ ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
+ ok(!delete_pf("msitest", FALSE), "File installed\n");
+ }
+
+ DeleteFile(msifile);
+ DeleteFile("augustus");
+}
+
+static void test_customaction51(void)
+{
+ UINT r;
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\augustus", 500);
+
+ create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
+ ok(delete_pf("msitest", FALSE), "File installed\n");
+
+ DeleteFile(msifile);
+ DeleteFile("msitest\\augustus");
+ RemoveDirectory("msitest");
+}
+
START_TEST(install)
{
DWORD len;
@@ -3717,6 +4305,11 @@ START_TEST(install)
test_cabisextracted();
test_concurrentinstall();
test_setpropertyfolder();
+ test_publish_registerproduct();
+ test_publish_publishproduct();
+ test_publish_publishfeatures();
+ test_publish_registeruser();
+ test_publish_processcomponents();
test_publish();
test_publishsourcelist();
test_transformprop();
@@ -3728,6 +4321,8 @@ START_TEST(install)
test_missingcab();
test_duplicatefiles();
test_writeregistryvalues();
+ test_sourcefolder();
+ test_customaction51();
SetCurrentDirectoryA(prev_path);
}
diff --git a/rostests/winetests/msi/msi.c b/rostests/winetests/msi/msi.c
index 520f0e77582..bb45d8da8fe 100644
--- a/rostests/winetests/msi/msi.c
+++ b/rostests/winetests/msi/msi.c
@@ -34,6 +34,8 @@ static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
(LPCSTR, LPCSTR, LPSTR, DWORD*);
static UINT (WINAPI *pMsiGetFileHashA)
(LPCSTR, DWORD, PMSIFILEHASHINFO);
+static UINT (WINAPI *pMsiGetProductInfoExA)
+ (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
static UINT (WINAPI *pMsiOpenPackageExA)
(LPCSTR, DWORD, MSIHANDLE*);
static UINT (WINAPI *pMsiOpenPackageExW)
@@ -55,6 +57,7 @@ static void init_functionpointers(void)
GET_PROC(hmsi, MsiGetComponentPathA)
GET_PROC(hmsi, MsiGetFileHashA)
+ GET_PROC(hmsi, MsiGetProductInfoExA)
GET_PROC(hmsi, MsiOpenPackageExA)
GET_PROC(hmsi, MsiOpenPackageExW)
GET_PROC(hmsi, MsiQueryComponentStateA)
@@ -301,7 +304,8 @@ static void test_MsiGetFileHash(void)
/* szFilePath is empty */
r = pMsiGetFileHashA("", 0, &hash);
- ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
+ ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
+ "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
/* szFilePath is nonexistent */
r = pMsiGetFileHashA(name, 0, &hash);
@@ -643,7 +647,7 @@ static void test_MsiQueryFeatureState(void)
state = MsiQueryFeatureStateA(prodcode, "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
- res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 8);
+ res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
state = MsiQueryFeatureStateA(prodcode, "feature");
@@ -2042,6 +2046,4000 @@ static void test_MsiGetFileVersion(void)
HeapFree(GetProcessHeap(), 0, langcheck);
}
+static void test_MsiGetProductInfo(void)
+{
+ UINT r;
+ LONG res;
+ HKEY propkey, source;
+ HKEY prodkey, localkey;
+ CHAR prodcode[MAX_PATH];
+ CHAR prod_squashed[MAX_PATH];
+ CHAR packcode[MAX_PATH];
+ CHAR pack_squashed[MAX_PATH];
+ CHAR buf[MAX_PATH];
+ CHAR keypath[MAX_PATH];
+ LPSTR usersid;
+ DWORD sz, val = 42;
+
+ create_test_guid(prodcode, prod_squashed);
+ create_test_guid(packcode, pack_squashed);
+ get_user_sid(&usersid);
+
+ /* NULL szProduct */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* empty szProduct */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* garbage szProduct */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* guid without brackets */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* guid with brackets */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* same length as guid, but random */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* not installed, NULL szAttribute */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* not installed, NULL lpValueBuf */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* not installed, NULL pcchValueBuf */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* created guid cannot possibly be an installed product code */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* managed product code exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* local user product code exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* both local and managed product code exist */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallProperties key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ /* pcchBuf is NULL */
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* lpValueBuf is NULL */
+ sz = MAX_PATH;
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ /* lpValueBuf is NULL, pcchValueBuf is too small */
+ sz = 2;
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ /* lpValueBuf is NULL, pcchValueBuf is too small */
+ sz = 2;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
+ ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
+ sz = 4;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"),
+ "Expected buf to remain unchanged, got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* random property not supported by MSI, value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ RegDeleteValueA(propkey, "IMadeThis");
+ RegDeleteValueA(propkey, "HelpLink");
+ RegDeleteKeyA(propkey, "");
+ RegDeleteKeyA(localkey, "");
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(propkey);
+ RegCloseKey(localkey);
+ RegCloseKey(prodkey);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* local user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallProperties key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ RegDeleteValueA(propkey, "HelpLink");
+ RegDeleteKeyA(propkey, "");
+ RegDeleteKeyA(localkey, "");
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(propkey);
+ RegCloseKey(localkey);
+ RegCloseKey(prodkey);
+
+ lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* classes product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* local user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallProperties key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ RegDeleteKeyA(propkey, "");
+ RegDeleteKeyA(localkey, "");
+ RegCloseKey(propkey);
+ RegCloseKey(localkey);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
+ lstrcatA(keypath, "S-1-5-18\\\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Local System product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallProperties key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayVersion", 0,
+ REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* UrlInfoAbout value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* UrlInfoAbout type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* UrlUpdateInfo value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* UrlUpdateInfo type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstanceType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstanceType type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstanceType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstanceType type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Assignment value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Assignment type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Assignment value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Assignment type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+ ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
+ ok(sz == 38, "Expected 38, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegCreateKeyA(prodkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
+ ok(sz == 8, "Expected 8, got %d\n", sz);
+
+ res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageName type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Authorized value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ if (r != ERROR_UNKNOWN_PROPERTY)
+ {
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ if (r != ERROR_UNKNOWN_PROPERTY)
+ {
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Authorized value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ if (r != ERROR_UNKNOWN_PROPERTY)
+ {
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
+ (const BYTE *)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp type is REG_DWORD */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ if (r != ERROR_UNKNOWN_PROPERTY)
+ {
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+ }
+
+ RegDeleteValueA(propkey, "HelpLink");
+ RegDeleteValueA(propkey, "DisplayName");
+ RegDeleteValueA(propkey, "DisplayVersion");
+ RegDeleteValueA(propkey, "HelpTelephone");
+ RegDeleteValueA(propkey, "InstallLocation");
+ RegDeleteValueA(propkey, "InstallSource");
+ RegDeleteValueA(propkey, "InstallDate");
+ RegDeleteValueA(propkey, "Publisher");
+ RegDeleteValueA(propkey, "LocalPackage");
+ RegDeleteValueA(propkey, "UrlInfoAbout");
+ RegDeleteValueA(propkey, "UrlUpdateInfo");
+ RegDeleteValueA(propkey, "VersionMinor");
+ RegDeleteValueA(propkey, "VersionMajor");
+ RegDeleteValueA(propkey, "ProductID");
+ RegDeleteValueA(propkey, "RegCompany");
+ RegDeleteValueA(propkey, "RegOwner");
+ RegDeleteValueA(propkey, "InstanceType");
+ RegDeleteValueA(propkey, "Transforms");
+ RegDeleteValueA(propkey, "Language");
+ RegDeleteValueA(propkey, "ProductName");
+ RegDeleteValueA(propkey, "Assignment");
+ RegDeleteValueA(propkey, "PackageCode");
+ RegDeleteValueA(propkey, "Version");
+ RegDeleteValueA(propkey, "ProductIcon");
+ RegDeleteValueA(propkey, "AuthorizedLUAApp");
+ RegDeleteKeyA(propkey, "");
+ RegDeleteKeyA(localkey, "");
+ RegDeleteValueA(prodkey, "InstanceType");
+ RegDeleteValueA(prodkey, "Transforms");
+ RegDeleteValueA(prodkey, "Language");
+ RegDeleteValueA(prodkey, "ProductName");
+ RegDeleteValueA(prodkey, "Assignment");
+ RegDeleteValueA(prodkey, "PackageCode");
+ RegDeleteValueA(prodkey, "Version");
+ RegDeleteValueA(prodkey, "ProductIcon");
+ RegDeleteValueA(prodkey, "AuthorizedLUAApp");
+ RegDeleteValueA(source, "PackageName");
+ RegDeleteKeyA(source, "");
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(propkey);
+ RegCloseKey(localkey);
+ RegCloseKey(source);
+ RegCloseKey(prodkey);
+}
+
+static void test_MsiGetProductInfoEx(void)
+{
+ UINT r;
+ LONG res;
+ HKEY propkey, userkey;
+ HKEY prodkey, localkey;
+ CHAR prodcode[MAX_PATH];
+ CHAR prod_squashed[MAX_PATH];
+ CHAR packcode[MAX_PATH];
+ CHAR pack_squashed[MAX_PATH];
+ CHAR buf[MAX_PATH];
+ CHAR keypath[MAX_PATH];
+ LPSTR usersid;
+ DWORD sz;
+
+ if (!pMsiGetProductInfoExA)
+ {
+ skip("MsiGetProductInfoExA is not available\n");
+ return;
+ }
+
+ create_test_guid(prodcode, prod_squashed);
+ create_test_guid(packcode, pack_squashed);
+ get_user_sid(&usersid);
+
+ /* NULL szProductCode */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* empty szProductCode */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* garbage szProductCode */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* guid without brackets */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* guid with brackets */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* szValue is non-NULL while pcchValue is NULL */
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+
+ /* dwContext is out of range */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid, 42,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* szProperty is NULL */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ NULL, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* szProperty is empty */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ "", buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* szProperty is not a valid property */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ "notvalid", buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* same length as guid, but random */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ /* MSIINSTALLCONTEXT_USERUNMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* local user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallProperties key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ RegDeleteValueA(propkey, "LocalPackage");
+
+ /* LocalPackage value must exist */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage exists, but HelpLink does not exist */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ /* szValue and pcchValue are NULL */
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* pcchValue is exactly 5 */
+ sz = 5;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_MORE_DATA,
+ "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 10, "Expected 10, got %d\n", sz);
+
+ /* szValue is NULL, pcchValue is exactly 5 */
+ sz = 5;
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(sz == 10, "Expected 10, got %d\n", sz);
+
+ /* szValue is NULL, pcchValue is MAX_PATH */
+ sz = MAX_PATH;
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(sz == 10, "Expected 10, got %d\n", sz);
+
+ /* pcchValue is exactly 0 */
+ sz = 0;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_MORE_DATA,
+ "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
+ ok(sz == 10, "Expected 10, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* szProperty is not a valid property */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ "notvalid", buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLInfoAbout value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLUpdateInfo value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* AssignmentType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ RegDeleteValueA(propkey, "AuthorizedLUAApp");
+ RegDeleteValueA(propkey, "PackageName");
+ RegDeleteValueA(propkey, "ProductIcon");
+ RegDeleteValueA(propkey, "Version");
+ RegDeleteValueA(propkey, "PackageCode");
+ RegDeleteValueA(propkey, "AssignmentType");
+ RegDeleteValueA(propkey, "ProductName");
+ RegDeleteValueA(propkey, "Language");
+ RegDeleteValueA(propkey, "Transforms");
+ RegDeleteValueA(propkey, "RegOwner");
+ RegDeleteValueA(propkey, "RegCompany");
+ RegDeleteValueA(propkey, "ProductID");
+ RegDeleteValueA(propkey, "DisplayVersion");
+ RegDeleteValueA(propkey, "VersionMajor");
+ RegDeleteValueA(propkey, "VersionMinor");
+ RegDeleteValueA(propkey, "URLUpdateInfo");
+ RegDeleteValueA(propkey, "URLInfoAbout");
+ RegDeleteValueA(propkey, "Publisher");
+ RegDeleteValueA(propkey, "LocalPackage");
+ RegDeleteValueA(propkey, "InstallSource");
+ RegDeleteValueA(propkey, "InstallLocation");
+ RegDeleteValueA(propkey, "DisplayName");
+ RegDeleteValueA(propkey, "InstallDate");
+ RegDeleteValueA(propkey, "HelpTelephone");
+ RegDeleteValueA(propkey, "HelpLink");
+ RegDeleteValueA(propkey, "LocalPackage");
+ RegDeleteKeyA(propkey, "");
+ RegCloseKey(propkey);
+ RegDeleteKeyA(localkey, "");
+ RegCloseKey(localkey);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLInfoAbout value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLUpdateInfo value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* AssignmentType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ todo_wine
+ {
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ RegDeleteValueA(prodkey, "AuthorizedLUAApp");
+ RegDeleteValueA(prodkey, "PackageName");
+ RegDeleteValueA(prodkey, "ProductIcon");
+ RegDeleteValueA(prodkey, "Version");
+ RegDeleteValueA(prodkey, "PackageCode");
+ RegDeleteValueA(prodkey, "AssignmentType");
+ RegDeleteValueA(prodkey, "ProductName");
+ RegDeleteValueA(prodkey, "Language");
+ RegDeleteValueA(prodkey, "Transforms");
+ RegDeleteValueA(prodkey, "RegOwner");
+ RegDeleteValueA(prodkey, "RegCompany");
+ RegDeleteValueA(prodkey, "ProductID");
+ RegDeleteValueA(prodkey, "DisplayVersion");
+ RegDeleteValueA(prodkey, "VersionMajor");
+ RegDeleteValueA(prodkey, "VersionMinor");
+ RegDeleteValueA(prodkey, "URLUpdateInfo");
+ RegDeleteValueA(prodkey, "URLInfoAbout");
+ RegDeleteValueA(prodkey, "Publisher");
+ RegDeleteValueA(prodkey, "LocalPackage");
+ RegDeleteValueA(prodkey, "InstallSource");
+ RegDeleteValueA(prodkey, "InstallLocation");
+ RegDeleteValueA(prodkey, "DisplayName");
+ RegDeleteValueA(prodkey, "InstallDate");
+ RegDeleteValueA(prodkey, "HelpTelephone");
+ RegDeleteValueA(prodkey, "HelpLink");
+ RegDeleteValueA(prodkey, "LocalPackage");
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+
+ /* MSIINSTALLCONTEXT_USERMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* local user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallProperties key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ManagedLocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLInfoAbout value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLUpdateInfo value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* AssignmentType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ RegDeleteValueA(propkey, "AuthorizedLUAApp");
+ RegDeleteValueA(propkey, "PackageName");
+ RegDeleteValueA(propkey, "ProductIcon");
+ RegDeleteValueA(propkey, "Version");
+ RegDeleteValueA(propkey, "PackageCode");
+ RegDeleteValueA(propkey, "AssignmentType");
+ RegDeleteValueA(propkey, "ProductName");
+ RegDeleteValueA(propkey, "Language");
+ RegDeleteValueA(propkey, "Transforms");
+ RegDeleteValueA(propkey, "RegOwner");
+ RegDeleteValueA(propkey, "RegCompany");
+ RegDeleteValueA(propkey, "ProductID");
+ RegDeleteValueA(propkey, "DisplayVersion");
+ RegDeleteValueA(propkey, "VersionMajor");
+ RegDeleteValueA(propkey, "VersionMinor");
+ RegDeleteValueA(propkey, "URLUpdateInfo");
+ RegDeleteValueA(propkey, "URLInfoAbout");
+ RegDeleteValueA(propkey, "Publisher");
+ RegDeleteValueA(propkey, "LocalPackage");
+ RegDeleteValueA(propkey, "InstallSource");
+ RegDeleteValueA(propkey, "InstallLocation");
+ RegDeleteValueA(propkey, "DisplayName");
+ RegDeleteValueA(propkey, "InstallDate");
+ RegDeleteValueA(propkey, "HelpTelephone");
+ RegDeleteValueA(propkey, "HelpLink");
+ RegDeleteValueA(propkey, "ManagedLocalPackage");
+ RegDeleteKeyA(propkey, "");
+ RegCloseKey(propkey);
+ RegDeleteKeyA(localkey, "");
+ RegCloseKey(localkey);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* current user product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists, user product key does not exist */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists, user product key does exist */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLInfoAbout value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLUpdateInfo value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* AssignmentType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ todo_wine
+ {
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ RegDeleteValueA(userkey, "AuthorizedLUAApp");
+ RegDeleteValueA(userkey, "PackageName");
+ RegDeleteValueA(userkey, "ProductIcon");
+ RegDeleteValueA(userkey, "Version");
+ RegDeleteValueA(userkey, "PackageCode");
+ RegDeleteValueA(userkey, "AssignmentType");
+ RegDeleteValueA(userkey, "ProductName");
+ RegDeleteValueA(userkey, "Language");
+ RegDeleteValueA(userkey, "Transforms");
+ RegDeleteValueA(userkey, "RegOwner");
+ RegDeleteValueA(userkey, "RegCompany");
+ RegDeleteValueA(userkey, "ProductID");
+ RegDeleteValueA(userkey, "DisplayVersion");
+ RegDeleteValueA(userkey, "VersionMajor");
+ RegDeleteValueA(userkey, "VersionMinor");
+ RegDeleteValueA(userkey, "URLUpdateInfo");
+ RegDeleteValueA(userkey, "URLInfoAbout");
+ RegDeleteValueA(userkey, "Publisher");
+ RegDeleteValueA(userkey, "LocalPackage");
+ RegDeleteValueA(userkey, "InstallSource");
+ RegDeleteValueA(userkey, "InstallLocation");
+ RegDeleteValueA(userkey, "DisplayName");
+ RegDeleteValueA(userkey, "InstallDate");
+ RegDeleteValueA(userkey, "HelpTelephone");
+ RegDeleteValueA(userkey, "HelpLink");
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+
+ /* MSIINSTALLCONTEXT_MACHINE */
+
+ /* szUserSid is non-NULL */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, usersid,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* local system product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallProperties key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLInfoAbout value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLUpdateInfo value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
+ ok(sz == 6, "Expected 6, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
+ ok(sz == 2, "Expected 2, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* AssignmentType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ RegDeleteValueA(propkey, "AuthorizedLUAApp");
+ RegDeleteValueA(propkey, "PackageName");
+ RegDeleteValueA(propkey, "ProductIcon");
+ RegDeleteValueA(propkey, "Version");
+ RegDeleteValueA(propkey, "PackageCode");
+ RegDeleteValueA(propkey, "AssignmentType");
+ RegDeleteValueA(propkey, "ProductName");
+ RegDeleteValueA(propkey, "Language");
+ RegDeleteValueA(propkey, "Transforms");
+ RegDeleteValueA(propkey, "RegOwner");
+ RegDeleteValueA(propkey, "RegCompany");
+ RegDeleteValueA(propkey, "ProductID");
+ RegDeleteValueA(propkey, "DisplayVersion");
+ RegDeleteValueA(propkey, "VersionMajor");
+ RegDeleteValueA(propkey, "VersionMinor");
+ RegDeleteValueA(propkey, "URLUpdateInfo");
+ RegDeleteValueA(propkey, "URLInfoAbout");
+ RegDeleteValueA(propkey, "Publisher");
+ RegDeleteValueA(propkey, "LocalPackage");
+ RegDeleteValueA(propkey, "InstallSource");
+ RegDeleteValueA(propkey, "InstallLocation");
+ RegDeleteValueA(propkey, "DisplayName");
+ RegDeleteValueA(propkey, "InstallDate");
+ RegDeleteValueA(propkey, "HelpTelephone");
+ RegDeleteValueA(propkey, "HelpLink");
+ RegDeleteValueA(propkey, "LocalPackage");
+ RegDeleteKeyA(propkey, "");
+ RegCloseKey(propkey);
+ RegDeleteKeyA(localkey, "");
+ RegCloseKey(localkey);
+
+ lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* local classes product key exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
+ ok(sz == 1, "Expected 1, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpLink value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_HELPLINK, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* HelpTelephone value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallDate value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLDATE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallLocation value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* InstallSource value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LocalPackage value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Publisher value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PUBLISHER, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLInfoAbout value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URLUpdateInfo value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMinor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* VersionMajor value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* DisplayVersion value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductID value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTID, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegCompany value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_REGCOMPANY, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* RegOwner value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_REGOWNER, buf, &sz);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Transforms value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_TRANSFORMS, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
+ ok(sz == 5, "Expected 5, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Language value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_LANGUAGE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* AssignmentType value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* FIXME */
+
+ /* PackageCode value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PACKAGECODE, buf, &sz);
+ todo_wine
+ {
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Version value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_VERSION, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
+ ok(sz == 3, "Expected 3, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* ProductIcon value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PRODUCTICON, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* PackageName value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_PACKAGENAME, buf, &sz);
+ todo_wine
+ {
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
+ ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
+ }
+
+ res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* AuthorizedLUAApp value exists */
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = pMsiGetProductInfoExA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
+ ok(sz == 4, "Expected 4, got %d\n", sz);
+
+ RegDeleteValueA(prodkey, "AuthorizedLUAApp");
+ RegDeleteValueA(prodkey, "PackageName");
+ RegDeleteValueA(prodkey, "ProductIcon");
+ RegDeleteValueA(prodkey, "Version");
+ RegDeleteValueA(prodkey, "PackageCode");
+ RegDeleteValueA(prodkey, "AssignmentType");
+ RegDeleteValueA(prodkey, "ProductName");
+ RegDeleteValueA(prodkey, "Language");
+ RegDeleteValueA(prodkey, "Transforms");
+ RegDeleteValueA(prodkey, "RegOwner");
+ RegDeleteValueA(prodkey, "RegCompany");
+ RegDeleteValueA(prodkey, "ProductID");
+ RegDeleteValueA(prodkey, "DisplayVersion");
+ RegDeleteValueA(prodkey, "VersionMajor");
+ RegDeleteValueA(prodkey, "VersionMinor");
+ RegDeleteValueA(prodkey, "URLUpdateInfo");
+ RegDeleteValueA(prodkey, "URLInfoAbout");
+ RegDeleteValueA(prodkey, "Publisher");
+ RegDeleteValueA(prodkey, "LocalPackage");
+ RegDeleteValueA(prodkey, "InstallSource");
+ RegDeleteValueA(prodkey, "InstallLocation");
+ RegDeleteValueA(prodkey, "DisplayName");
+ RegDeleteValueA(prodkey, "InstallDate");
+ RegDeleteValueA(prodkey, "HelpTelephone");
+ RegDeleteValueA(prodkey, "HelpLink");
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+}
+
START_TEST(msi)
{
init_functionpointers();
@@ -2062,6 +6060,8 @@ START_TEST(msi)
test_MsiGetComponentPath();
test_MsiGetProductCode();
test_MsiEnumClients();
+ test_MsiGetProductInfo();
+ test_MsiGetProductInfoEx();
}
test_MsiGetFileVersion();
diff --git a/rostests/winetests/msi/msi.rbuild b/rostests/winetests/msi/msi.rbuild
index 545c8e3e842..677dfa0055b 100644
--- a/rostests/winetests/msi/msi.rbuild
+++ b/rostests/winetests/msi/msi.rbuild
@@ -1,7 +1,7 @@
-
+
.
0x600
0x600
diff --git a/rostests/winetests/msi/package.c b/rostests/winetests/msi/package.c
index dc0e31ec41c..232b75e9cfb 100644
--- a/rostests/winetests/msi/package.c
+++ b/rostests/winetests/msi/package.c
@@ -922,10 +922,12 @@ static void test_settargetpath(void)
sprintf( tempdir, "%s\\subdir", buffer );
r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
- ok( r == ERROR_SUCCESS, "MsiSetTargetPath on file returned %d\n", r );
+ ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
+ "MsiSetTargetPath on file returned %d\n", r );
r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
- ok( r == ERROR_SUCCESS, "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
+ ok( r == ERROR_SUCCESS || r == ERROR_DIRECTORY,
+ "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
DeleteFile( buffer );
@@ -986,6 +988,9 @@ static void test_condition(void)
r = MsiEvaluateCondition(hpkg, "0");
ok( r == MSICONDITION_FALSE, "wrong return val\n");
+ r = MsiEvaluateCondition(hpkg, "-1");
+ ok( r == MSICONDITION_TRUE, "wrong return val\n");
+
r = MsiEvaluateCondition(hpkg, "0 = 0");
ok( r == MSICONDITION_TRUE, "wrong return val\n");
@@ -1622,6 +1627,10 @@ static void test_condition(void)
r = MsiEvaluateCondition(hpkg, "X !=\"\" and (X =\"5.0\" or X =\"5.1\" or X =\"6.0\")");
ok( r == MSICONDITION_ERROR, "wrong return val (%d)\n", r);
+ /* feature doesn't exist */
+ r = MsiEvaluateCondition(hpkg, "&nofeature");
+ ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
+
MsiCloseHandle( hpkg );
DeleteFile(msifile);
}
@@ -4697,7 +4706,8 @@ static void test_installprops(void)
CHAR path[MAX_PATH];
CHAR buf[MAX_PATH];
DWORD size, type;
- HKEY hkey;
+ LANGID langid;
+ HKEY hkey1, hkey2;
UINT r;
GetCurrentDirectory(MAX_PATH, path);
@@ -4717,25 +4727,46 @@ static void test_installprops(void)
ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
- RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
+ RegOpenKey(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
+
+ RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hkey2);
size = MAX_PATH;
type = REG_SZ;
- RegQueryValueEx(hkey, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
+ *path = '\0';
+ if (RegQueryValueEx(hkey1, "DefName", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
+ {
+ size = MAX_PATH;
+ type = REG_SZ;
+ RegQueryValueEx(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
+ }
- size = MAX_PATH;
- r = MsiGetProperty(hpkg, "USERNAME", buf, &size);
- ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
- ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
+ /* win9x doesn't set this */
+ if (*path)
+ {
+ size = MAX_PATH;
+ r = MsiGetProperty(hpkg, "USERNAME", buf, &size);
+ ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+ ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
+ }
size = MAX_PATH;
type = REG_SZ;
- RegQueryValueEx(hkey, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
+ *path = '\0';
+ if (RegQueryValueEx(hkey1, "DefCompany", NULL, &type, (LPBYTE)path, &size) != ERROR_SUCCESS)
+ {
+ size = MAX_PATH;
+ type = REG_SZ;
+ RegQueryValueEx(hkey2, "RegisteredOrganization", NULL, &type, (LPBYTE)path, &size);
+ }
- size = MAX_PATH;
- r = MsiGetProperty(hpkg, "COMPANYNAME", buf, &size);
- ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
- ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
+ if (*path)
+ {
+ size = MAX_PATH;
+ r = MsiGetProperty(hpkg, "COMPANYNAME", buf, &size);
+ ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+ ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
+ }
size = MAX_PATH;
r = MsiGetProperty(hpkg, "VersionDatabase", buf, &size);
@@ -4762,7 +4793,16 @@ static void test_installprops(void)
ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
trace("PackageCode = %s\n", buf);
- CloseHandle(hkey);
+ langid = GetUserDefaultLangID();
+ sprintf(path, "%d", langid);
+
+ size = MAX_PATH;
+ r = MsiGetProperty(hpkg, "UserLanguageID", buf, &size);
+ ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS< got %d\n", r);
+ ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
+
+ CloseHandle(hkey1);
+ CloseHandle(hkey2);
MsiCloseHandle(hpkg);
DeleteFile(msifile);
}
@@ -5294,7 +5334,8 @@ static void test_complocator(void)
lstrcpyA(expected, CURR_DIR);
lstrcatA(expected, "\\abelisaurus");
- ok(!lstrcmpA(prop, expected), "Expected %s, got %s\n", expected, prop);
+ ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
+ "Expected %s or empty string, got %s\n", expected, prop);
size = MAX_PATH;
r = MsiGetPropertyA(hpkg, "BACTROSAURUS", prop, &size);
@@ -5317,7 +5358,8 @@ static void test_complocator(void)
lstrcpyA(expected, CURR_DIR);
lstrcatA(expected, "\\");
- ok(!lstrcmpA(prop, expected), "Expected %s, got %s\n", expected, prop);
+ ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
+ "Expected %s or empty string, got %s\n", expected, prop);
size = MAX_PATH;
r = MsiGetPropertyA(hpkg, "FALCARIUS", prop, &size);
@@ -5360,7 +5402,8 @@ static void test_complocator(void)
lstrcpyA(expected, CURR_DIR);
lstrcatA(expected, "\\");
- ok(!lstrcmpA(prop, expected), "Expected %s, got %s\n", expected, prop);
+ ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
+ "Expected %s or empty string, got %s\n", expected, prop);
size = MAX_PATH;
r = MsiGetPropertyA(hpkg, "NEOSODON", prop, &size);
@@ -5368,7 +5411,8 @@ static void test_complocator(void)
lstrcpyA(expected, CURR_DIR);
lstrcatA(expected, "\\neosodon\\");
- ok(!lstrcmpA(prop, expected), "Expected %s, got %s\n", expected, prop);
+ ok(!lstrcmpA(prop, expected) || !lstrcmpA(prop, ""),
+ "Expected %s or empty string, got %s\n", expected, prop);
size = MAX_PATH;
r = MsiGetPropertyA(hpkg, "OLOROTITAN", prop, &size);
diff --git a/rostests/winetests/msi/record.c b/rostests/winetests/msi/record.c
index 1f72d128617..471fc9ce372 100644
--- a/rostests/winetests/msi/record.c
+++ b/rostests/winetests/msi/record.c
@@ -351,7 +351,35 @@ static void test_msirecord(void)
DeleteFile(filename); /* Delete it for sure, when everything else is closed. */
}
+static void test_MsiRecordGetString(void)
+{
+ MSIHANDLE rec;
+ CHAR buf[MAX_PATH];
+ DWORD sz;
+ UINT r;
+
+ rec = MsiCreateRecord(2);
+ ok(rec != 0, "Expected a valid handle\n");
+
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiRecordGetString(rec, 1, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ sz = MAX_PATH;
+ lstrcpyA(buf, "apple");
+ r = MsiRecordGetString(rec, 10, buf, &sz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
+ ok(sz == 0, "Expected 0, got %d\n", sz);
+
+ MsiCloseHandle(rec);
+}
+
START_TEST(record)
{
test_msirecord();
+ test_MsiRecordGetString();
}
diff --git a/rostests/winetests/msi/source.c b/rostests/winetests/msi/source.c
index 7407f5b8748..aef15ba782f 100644
--- a/rostests/winetests/msi/source.c
+++ b/rostests/winetests/msi/source.c
@@ -31,10 +31,21 @@
#include "wine/test.h"
static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
-static UINT (WINAPI *pMsiSourceListGetInfoA)
- (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
+static UINT (WINAPI *pMsiSourceListAddMediaDiskA)
+ (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPCSTR, LPCSTR);
static UINT (WINAPI *pMsiSourceListAddSourceExA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, DWORD);
+static UINT (WINAPI *pMsiSourceListEnumMediaDisksA)
+ (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPDWORD, LPSTR,
+ LPDWORD, LPSTR, LPDWORD);
+static UINT (WINAPI *pMsiSourceListEnumSourcesA)
+ (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
+static UINT (WINAPI *pMsiSourceListGetInfoA)
+ (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
+static UINT (WINAPI *pMsiSourceListSetInfoA)
+ (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD,LPCSTR, LPCSTR);
+static UINT (WINAPI *pMsiSourceListAddSourceA)
+ (LPCSTR, LPCSTR, DWORD, LPCSTR);
static void init_functionpointers(void)
{
@@ -46,8 +57,13 @@ static void init_functionpointers(void)
if(!p ## func) \
trace("GetProcAddress(%s) failed\n", #func);
+ GET_PROC(hmsi, MsiSourceListAddMediaDiskA)
GET_PROC(hmsi, MsiSourceListAddSourceExA)
+ GET_PROC(hmsi, MsiSourceListEnumMediaDisksA)
+ GET_PROC(hmsi, MsiSourceListEnumSourcesA)
GET_PROC(hmsi, MsiSourceListGetInfoA)
+ GET_PROC(hmsi, MsiSourceListSetInfoA)
+ GET_PROC(hmsi, MsiSourceListAddSourceA)
GET_PROC(hadvapi32, ConvertSidToStringSidA)
@@ -106,20 +122,54 @@ static void create_test_guid(LPSTR prodcode, LPSTR squashed)
WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
}
-static void get_user_sid(LPSTR *usersid)
+static int get_user_sid(LPSTR *usersid)
{
HANDLE token;
BYTE buf[1024];
DWORD size;
PTOKEN_USER user;
+ BOOL rc;
- OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
+ rc=OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
+ if (!rc && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ return 0;
size = sizeof(buf);
GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
user = (PTOKEN_USER)buf;
pConvertSidToStringSidA(user->User.Sid, usersid);
+ return 1;
}
+static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
+{
+ char val[MAX_PATH];
+ DWORD size, type;
+ LONG res;
+
+ size = MAX_PATH;
+ val[0] = '\0';
+ res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
+
+ if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
+ {
+ ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
+ return;
+ }
+
+ if (!expected)
+ ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
+ else
+ {
+ if (bcase)
+ ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
+ else
+ ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
+ }
+}
+
+#define CHECK_REG_STR(prodkey, name, expected) \
+ check_reg_str(prodkey, name, expected, TRUE, __LINE__);
+
static void test_MsiSourceListGetInfo(void)
{
CHAR prodcode[MAX_PATH];
@@ -130,7 +180,7 @@ static void test_MsiSourceListGetInfo(void)
LPCSTR data;
LONG res;
UINT r;
- HKEY userkey, hkey;
+ HKEY userkey, hkey, media;
DWORD size;
if (!pMsiSourceListGetInfoA)
@@ -140,7 +190,11 @@ static void test_MsiSourceListGetInfo(void)
}
create_test_guid(prodcode, prod_squashed);
- get_user_sid(&usersid);
+ if (!get_user_sid(&usersid))
+ {
+ skip("User SID not available -> skipping MsiSourceListGetInfoA tests\n");
+ return;
+ }
/* NULL szProductCodeOrPatchCode */
r = pMsiSourceListGetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
@@ -218,6 +272,7 @@ static void test_MsiSourceListGetInfo(void)
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
/* size is non-NULL while value is NULL */
+ size = MAX_PATH;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
@@ -229,6 +284,7 @@ static void test_MsiSourceListGetInfo(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* user product key exists */
+ size = MAX_PATH;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
@@ -302,6 +358,206 @@ static void test_MsiSourceListGetInfo(void)
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(size == 11, "Expected 11, got %d\n", size);
+ /* INSTALLPROPERTY_MEDIAPACKAGEPATH, media key does not exist */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
+ ok(size == 0, "Expected 0, got %d\n", size);
+
+ res = RegCreateKeyA(hkey, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ data = "path";
+ res = RegSetValueExA(media, "MediaPackage", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_MEDIAPACKAGEPATH */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "path"), "Expected \"path\", got \"%s\"\n", value);
+ ok(size == 4, "Expected 4, got %d\n", size);
+
+ /* INSTALLPROPERTY_DISKPROMPT */
+ data = "prompt";
+ res = RegSetValueExA(media, "DiskPrompt", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "prompt"), "Expected \"prompt\", got \"%s\"\n", value);
+ ok(size == 6, "Expected 6, got %d\n", size);
+
+ data = "";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, source is empty */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
+ ok(size == 0, "Expected 0, got %d\n", size);
+
+ data = "source";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value);
+ ok(size == 6, "Expected 6, got %d\n", size);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, size is too short */
+ size = 4;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE,
+ value, &size);
+ ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value);
+ ok(size == 6, "Expected 6, got %d\n", size);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, size is exactly 6 */
+ size = 6;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE,
+ value, &size);
+ ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value);
+ ok(size == 6, "Expected 6, got %d\n", size);
+
+ data = "a;source";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, one semi-colon */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value);
+ ok(size == 6, "Expected 6, got %d\n", size);
+
+ data = "a:source";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, one colon */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "a:source"), "Expected \"a:source\", got \"%s\"\n", value);
+ ok(size == 8, "Expected 8, got %d\n", size);
+
+ /* INSTALLPROPERTY_LASTUSEDTYPE, invalid source format */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
+ ok(size == 0, "Expected 0, got %d\n", size);
+
+ data = "x;y;z";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDTYPE, invalid source format */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
+ ok(size == 0, "Expected 0, got %d\n", size);
+
+ data = "n;y;z";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDTYPE */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
+ ok(size == 1, "Expected 1, got %d\n", size);
+
+ data = "negatory";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDTYPE */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
+ ok(size == 1, "Expected 1, got %d\n", size);
+
+ data = "megatron";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDTYPE */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "m"), "Expected \"m\", got \"%s\"\n", value);
+ ok(size == 1, "Expected 1, got %d\n", size);
+
+ data = "useless";
+ res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
+ (const BYTE *)data, lstrlenA(data) + 1);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* INSTALLPROPERTY_LASTUSEDTYPE */
+ size = MAX_PATH;
+ r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE,
+ value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "u"), "Expected \"u\", got \"%s\"\n", value);
+ ok(size == 1, "Expected 1, got %d\n", size);
+
+ RegDeleteValueA(media, "MediaPackage");
+ RegDeleteValueA(media, "DiskPrompt");
+ RegDeleteKeyA(media, "");
+ RegDeleteValueA(hkey, "LastUsedSource");
RegDeleteValueA(hkey, "nonexistent");
RegDeleteValueA(hkey, "PackageName");
RegDeleteKeyA(hkey, "");
@@ -367,7 +623,11 @@ static void test_MsiSourceListAddSourceEx(void)
}
create_test_guid(prodcode, prod_squashed);
- get_user_sid(&usersid);
+ if (!get_user_sid(&usersid))
+ {
+ skip("User SID not available -> skipping MsiSourceListAddSourceExA tests\n");
+ return;
+ }
/* GetLastError is not set by the function */
@@ -716,10 +976,2336 @@ static void test_MsiSourceListAddSourceEx(void)
HeapFree(GetProcessHeap(), 0, usersid);
}
+static void test_MsiSourceListEnumSources(void)
+{
+ CHAR prodcode[MAX_PATH];
+ CHAR prod_squashed[MAX_PATH];
+ CHAR keypath[MAX_PATH*2];
+ CHAR value[MAX_PATH];
+ LPSTR usersid;
+ LONG res;
+ UINT r;
+ HKEY prodkey, userkey;
+ HKEY url, net, source;
+ DWORD size;
+
+ if (!pMsiSourceListEnumSourcesA)
+ {
+ skip("MsiSourceListEnumSourcesA is not available\n");
+ return;
+ }
+
+ create_test_guid(prodcode, prod_squashed);
+ if (!get_user_sid(&usersid))
+ {
+ skip("User SID not available -> skipping MsiSourceListEnumSourcesA tests\n");
+ return;
+ }
+
+ /* GetLastError is not set by the function */
+
+ /* NULL szProductCodeOrPatchCode */
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ /* empty szProductCodeOrPatchCode */
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ /* garbage szProductCodeOrPatchCode */
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ /* guid without brackets */
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ /* guid with brackets */
+ size = 0xdeadbeef;
+ r = pMsiSourceListEnumSourcesA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
+
+ /* MSIINSTALLCONTEXT_USERUNMANAGED */
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(source, "URL", &url);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URL key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ res = RegSetValueExA(url, "2", 0, REG_SZ, (LPBYTE)"second", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ res = RegSetValueExA(url, "4", 0, REG_SZ, (LPBYTE)"fourth", 7);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* sources exist */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ /* try index 0 again */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ /* both szSource and pcchSource are NULL, index 0 */
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* both szSource and pcchSource are NULL, index 1 */
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, NULL, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* size is exactly 5 */
+ size = 5;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ /* szSource is non-NULL while pcchSource is NULL */
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, NULL);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
+
+ /* try index 1 after failure */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* reset the enumeration */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ /* try index 1 */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "second"), "Expected \"second\", got %s\n", value);
+ ok(size == 6, "Expected 6, got %d\n", size);
+
+ /* try index 1 again */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* try index 2 */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 2, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* try index < 0 */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, -1, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* NULL szUserSid */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PATCH, 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSICODE_PATCH | MSISOURCETYPE_URL,
+ 0, value, &size);
+ ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL,
+ 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ RegDeleteValueA(url, "1");
+ RegDeleteValueA(url, "2");
+ RegDeleteValueA(url, "4");
+ RegDeleteKeyA(url, "");
+ RegCloseKey(url);
+
+ /* SourceList key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Net key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* sources exist */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_USERMANAGED */
+
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(source, "URL", &url);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URL key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* sources exist */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ /* NULL szUserSid */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ RegDeleteValueA(url, "1");
+ RegDeleteKeyA(url, "");
+ RegCloseKey(url);
+
+ /* SourceList key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Net key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* sources exist */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_MACHINE */
+
+ /* szUserSid is non-NULL */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, usersid,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ /* szUserSid is non-NULL */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(prodkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(source, "URL", &url);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* URL key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* sources exist */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ /* NULL szUserSid */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ RegDeleteValueA(url, "1");
+ RegDeleteKeyA(url, "");
+ RegCloseKey(url);
+
+ /* SourceList key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegCreateKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Net key exists */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
+ ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
+
+ res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* sources exist */
+ size = MAX_PATH;
+ lstrcpyA(value, "aaa");
+ r = pMsiSourceListEnumSourcesA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
+ ok(size == 5, "Expected 5, got %d\n", size);
+
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+}
+
+static void test_MsiSourceListSetInfo(void)
+{
+ CHAR prodcode[MAX_PATH];
+ CHAR prod_squashed[MAX_PATH];
+ CHAR keypath[MAX_PATH*2];
+ HKEY prodkey, userkey;
+ HKEY net, url, media, source;
+ LPSTR usersid;
+ LONG res;
+ UINT r;
+
+ if (!pMsiSourceListSetInfoA)
+ {
+ skip("MsiSourceListSetInfoA is not available\n");
+ return;
+ }
+
+ create_test_guid(prodcode, prod_squashed);
+ if (!get_user_sid(&usersid))
+ {
+ skip("User SID not available -> skipping MsiSourceListSetInfoA tests\n");
+ return;
+ }
+
+ /* GetLastError is not set by the function */
+
+ /* NULL szProductCodeOrPatchCode */
+ r = pMsiSourceListSetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* empty szProductCodeOrPatchCode */
+ r = pMsiSourceListSetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* garbage szProductCodeOrPatchCode */
+ r = pMsiSourceListSetInfoA("garbage", usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid without brackets */
+ r = pMsiSourceListSetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid with brackets */
+ r = pMsiSourceListSetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* dwOptions is MSICODE_PRODUCT */
+ r = pMsiSourceListSetInfoA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* dwOptions is MSICODE_PATCH */
+ r = pMsiSourceListSetInfoA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PATCH,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
+
+ /* dwOptions is both MSICODE_PRODUCT and MSICODE_PATCH */
+ r = pMsiSourceListSetInfoA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSICODE_PATCH | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
+
+ /* dwOptions has both MSISOURCETYPE_NETWORK and MSISOURCETYPE_URL */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* LastUsedSource and dwOptions has both
+ * MSISOURCETYPE_NETWORK and MSISOURCETYPE_URL
+ */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "path");
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* LastUsedSource and dwOptions has no source type */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "path");
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* MSIINSTALLCONTEXT_USERUNMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists, no source type */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Media key is created by MsiSourceListSetInfo */
+ res = RegOpenKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ CHECK_REG_STR(media, "MediaPackage", "path");
+
+ /* set the info again */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path2");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ CHECK_REG_STR(media, "MediaPackage", "path2");
+
+ /* NULL szProperty */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ NULL, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* empty szProperty */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ "", "path");
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+
+ /* NULL szValue */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, NULL);
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+
+ /* empty szValue */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ CHECK_REG_STR(media, "MediaPackage", "");
+
+ /* INSTALLPROPERTY_MEDIAPACKAGEPATH, MSISOURCETYPE_NETWORK */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_MEDIAPACKAGEPATH, MSISOURCETYPE_URL */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_DISKPROMPT */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_DISKPROMPT, "prompt");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ CHECK_REG_STR(media, "DiskPrompt", "prompt");
+
+ /* INSTALLPROPERTY_DISKPROMPT, MSISOURCETYPE_NETWORK */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_DISKPROMPT, "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_DISKPROMPT, MSISOURCETYPE_URL */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_DISKPROMPT, "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "source");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_NETWORK */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "source");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Net key is created by MsiSourceListSetInfo */
+ res = RegOpenKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ CHECK_REG_STR(net, "1", "source\\")
+ CHECK_REG_STR(source, "LastUsedSource", "n;1;source");
+
+ /* source has forward slash */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "source/");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ CHECK_REG_STR(net, "1", "source\\");
+ CHECK_REG_STR(net, "2", "source/\\");
+ CHECK_REG_STR(source, "LastUsedSource", "n;2;source/");
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_URL */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "source");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* URL key is created by MsiSourceListSetInfo */
+ res = RegOpenKeyA(source, "URL", &url);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ CHECK_REG_STR(url, "1", "source/");
+ CHECK_REG_STR(source, "LastUsedSource", "u;1;source");
+
+ /* source has backslash */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "source\\");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ CHECK_REG_STR(url, "1", "source/");
+ CHECK_REG_STR(url, "2", "source\\/");
+ CHECK_REG_STR(source, "LastUsedSource", "u;2;source\\");
+
+ /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_MEDIA */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_MEDIA,
+ INSTALLPROPERTY_LASTUSEDSOURCE, "source");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_PACKAGENAME */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_PACKAGENAME, "name");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ CHECK_REG_STR(source, "PackageName", "name");
+
+ /* INSTALLPROPERTY_PACKAGENAME, MSISOURCETYPE_NETWORK */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_PACKAGENAME, "name");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_PACKAGENAME, MSISOURCETYPE_URL */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL,
+ INSTALLPROPERTY_PACKAGENAME, "name");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* INSTALLPROPERTY_LASTUSEDTYPE */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDTYPE, "type");
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+
+ /* definitely unknown property */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
+ "unknown", "val");
+ ok(r == ERROR_UNKNOWN_PROPERTY,
+ "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
+
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+ RegDeleteValueA(url, "1");
+ RegDeleteKeyA(url, "");
+ RegCloseKey(url);
+ RegDeleteValueA(media, "MediaPackage");
+ RegDeleteValueA(media, "DiskPrompt");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteValueA(source, "PackageName");
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_USERMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists, no source type */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Media key is created by MsiSourceListSetInfo */
+ res = RegOpenKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ CHECK_REG_STR(media, "MediaPackage", "path");
+
+ RegDeleteValueA(media, "MediaPackage");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_MACHINE */
+
+ lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(prodkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists, no source type */
+ r = pMsiSourceListSetInfoA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Media key is created by MsiSourceListSetInfo */
+ res = RegOpenKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ CHECK_REG_STR(media, "MediaPackage", "path");
+
+ /* szUserSid is non-NULL */
+ r = pMsiSourceListSetInfoA(prodcode, usersid,
+ MSIINSTALLCONTEXT_MACHINE, MSICODE_PRODUCT,
+ INSTALLPROPERTY_MEDIAPACKAGEPATH, "path");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ RegDeleteValueA(media, "MediaPackage");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+}
+
+static void test_MsiSourceListAddMediaDisk(void)
+{
+ CHAR prodcode[MAX_PATH];
+ CHAR prod_squashed[MAX_PATH];
+ CHAR keypath[MAX_PATH*2];
+ HKEY prodkey, userkey;
+ HKEY media, source;
+ LPSTR usersid;
+ LONG res;
+ UINT r;
+
+ if (!pMsiSourceListAddMediaDiskA)
+ {
+ skip("MsiSourceListAddMediaDiskA is not available\n");
+ return;
+ }
+
+ create_test_guid(prodcode, prod_squashed);
+ if (!get_user_sid(&usersid))
+ {
+ skip("User SID not available -> skipping MsiSourceListAddMediaDiskA tests\n");
+ return;
+ }
+
+ /* GetLastError is not set by the function */
+
+ /* NULL szProductCodeOrPatchCode */
+ r = pMsiSourceListAddMediaDiskA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* empty szProductCodeOrPatchCode */
+ r = pMsiSourceListAddMediaDiskA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* garbage szProductCodeOrPatchCode */
+ r = pMsiSourceListAddMediaDiskA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid without brackets */
+ r = pMsiSourceListAddMediaDiskA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid with brackets */
+ r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* dwOptions has MSISOURCETYPE_NETWORK */
+ r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* dwOptions has MSISOURCETYPE_URL */
+ r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL,
+ 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* dwOptions has MSISOURCETYPE_MEDIA */
+ r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_MEDIA,
+ 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* MSIINSTALLCONTEXT_USERUNMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Media subkey is created by MsiSourceListAddMediaDisk */
+ res = RegOpenKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(media, "1", "label;prompt");
+
+ /* dwDiskId is random */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 42, "label42", "prompt42");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(media, "1", "label;prompt");
+ CHECK_REG_STR(media, "42", "label42;prompt42");
+
+ /* dwDiskId is 0 */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, "label0", "prompt0");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(media, "0", "label0;prompt0");
+ CHECK_REG_STR(media, "1", "label;prompt");
+ CHECK_REG_STR(media, "42", "label42;prompt42");
+
+ /* dwDiskId is < 0 */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, -1, "label-1", "prompt-1");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(media, "-1", "label-1;prompt-1");
+ CHECK_REG_STR(media, "0", "label0;prompt0");
+ CHECK_REG_STR(media, "1", "label;prompt");
+ CHECK_REG_STR(media, "42", "label42;prompt42");
+
+ /* update dwDiskId 1 */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "newlabel", "newprompt");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(media, "-1", "label-1;prompt-1");
+ CHECK_REG_STR(media, "0", "label0;prompt0");
+ CHECK_REG_STR(media, "1", "newlabel;newprompt");
+ CHECK_REG_STR(media, "42", "label42;prompt42");
+
+ /* update dwDiskId 1, szPrompt is NULL */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "etiqueta", NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(media, "-1", "label-1;prompt-1");
+ CHECK_REG_STR(media, "0", "label0;prompt0");
+ CHECK_REG_STR(media, "1", "etiqueta;");
+ CHECK_REG_STR(media, "42", "label42;prompt42");
+
+ /* update dwDiskId 1, szPrompt is empty */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "etikett", "");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* update dwDiskId 1, szVolumeLable is NULL */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, NULL, "provocar");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(media, "-1", "label-1;prompt-1");
+ CHECK_REG_STR(media, "0", "label0;prompt0");
+ CHECK_REG_STR(media, "1", ";provocar");
+ CHECK_REG_STR(media, "42", "label42;prompt42");
+
+ /* update dwDiskId 1, szVolumeLable is empty */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, "", "provoquer");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* szUserSid is NULL */
+ r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, NULL, "provoquer");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(media, "-1", "label-1;prompt-1");
+ CHECK_REG_STR(media, "0", "label0;prompt0");
+ CHECK_REG_STR(media, "1", ";provoquer");
+ CHECK_REG_STR(media, "42", "label42;prompt42");
+
+ RegDeleteValueA(media, "-1");
+ RegDeleteValueA(media, "0");
+ RegDeleteValueA(media, "1");
+ RegDeleteValueA(media, "42");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_USERMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Media subkey is created by MsiSourceListAddMediaDisk */
+ res = RegOpenKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(media, "1", "label;prompt");
+
+ RegDeleteValueA(media, "1");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_MACHINE */
+
+ lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* machine product key exists */
+ r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(prodkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Media subkey is created by MsiSourceListAddMediaDisk */
+ res = RegOpenKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(media, "1", "label;prompt");
+
+ /* szUserSid is non-NULL */
+ r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
+ MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 1, "label", "prompt");
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ RegDeleteValueA(media, "1");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+}
+
+static void test_MsiSourceListEnumMediaDisks(void)
+{
+ CHAR prodcode[MAX_PATH];
+ CHAR prod_squashed[MAX_PATH];
+ CHAR keypath[MAX_PATH*2];
+ CHAR label[MAX_PATH];
+ CHAR prompt[MAX_PATH];
+ HKEY prodkey, userkey;
+ HKEY media, source;
+ DWORD labelsz, promptsz;
+ LPSTR usersid;
+ DWORD val;
+ DWORD id;
+ LONG res;
+ UINT r;
+
+ if (!pMsiSourceListEnumMediaDisksA)
+ {
+ skip("MsiSourceListEnumMediaDisksA is not available\n");
+ return;
+ }
+
+ create_test_guid(prodcode, prod_squashed);
+ if (!get_user_sid(&usersid))
+ {
+ skip("User SID not available -> skipping MsiSourceListEnumMediaDisksA tests\n");
+ return;
+ }
+
+ /* GetLastError is not set by the function */
+
+ /* NULL szProductCodeOrPatchCode */
+ r = pMsiSourceListEnumMediaDisksA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* empty szProductCodeOrPatchCode */
+ r = pMsiSourceListEnumMediaDisksA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* garbage szProductCodeOrPatchCode */
+ r = pMsiSourceListEnumMediaDisksA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid without brackets */
+ r = pMsiSourceListEnumMediaDisksA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid with brackets */
+ r = pMsiSourceListEnumMediaDisksA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
+ usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_UNKNOWN_PRODUCT,
+ "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* dwOptions has MSISOURCETYPE_NETWORK */
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
+ 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* dwOptions has MSISOURCETYPE_URL */
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_URL,
+ 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* dwIndex is non-zero */
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* MSIINSTALLCONTEXT_USERUNMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = 0xdeadbeef;
+ lstrcpyA(prompt, "bbb");
+ promptsz = 0xdeadbeef;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
+
+ res = RegCreateKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Media key exists */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = 0xdeadbeef;
+ lstrcpyA(prompt, "bbb");
+ promptsz = 0xdeadbeef;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label;prompt", 13);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* disk exists */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "2", 0, REG_SZ, (LPBYTE)"one;two", 8);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* now disk 2 exists, get the sizes */
+ id = 0;
+ labelsz = MAX_PATH;
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, &id, NULL, &labelsz,
+ NULL, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 2, "Expected 2, got %d\n", id);
+ ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
+ ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
+
+ /* now fill in the values */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "4", 0, REG_SZ, (LPBYTE)"three;four", 11);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* disks 1, 2, 4 exist, reset the enumeration */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* disks 1, 2, 4 exist, index 1 */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 2, "Expected 2, got %d\n", id);
+ ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
+ ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
+ ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
+
+ /* disks 1, 2, 4 exist, index 2 */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 2, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 4, "Expected 4, got %d\n", id);
+ ok(!lstrcmpA(label, "three"), "Expected \"three\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "four"), "Expected \"four\", got \"%s\"\n", prompt);
+ ok(promptsz == 4, "Expected 4, got %d\n", promptsz);
+
+ /* disks 1, 2, 4 exist, index 3, invalid */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 3, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
+
+ /* disks 1, 2, 4 exist, reset the enumeration */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* try index 0 again */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* jump to index 2 */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 2, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
+
+ /* after error, try index 1 */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 2, "Expected 2, got %d\n", id);
+ ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
+ ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
+ ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
+
+ /* try index 1 again */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 1, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
+
+ /* NULL pdwDiskId */
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, NULL, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* szVolumeLabel is NULL */
+ id = 0;
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, NULL, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* szVolumeLabel and pcchVolumeLabel are NULL */
+ id = 0;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, NULL, NULL,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* szVolumeLabel is non-NULL while pcchVolumeLabel is NULL */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, NULL,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* szDiskPrompt is NULL */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ NULL, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* szDiskPrompt and pcchDiskPrompt are NULL */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ NULL, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+
+ /* szDiskPrompt is non-NULL while pcchDiskPrompt is NULL */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, NULL);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+
+ /* pcchVolumeLabel is exactly 5 */
+ lstrcpyA(label, "aaa");
+ labelsz = 5;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, NULL, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* pcchDiskPrompt is exactly 6 */
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = 6;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, NULL, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label", 13);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* no semicolon */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "label"), "Expected \"label\", got \"%s\"\n", prompt);
+ ok(promptsz == 5, "Expected 5, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label;", 13);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* semicolon, no disk prompt */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, ""), "Expected \"\", got \"%s\"\n", prompt);
+ ok(promptsz == 0, "Expected 0, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)";prompt", 13);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* semicolon, label doesn't exist */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, ""), "Expected \"\", got \"%s\"\n", label);
+ ok(labelsz == 0, "Expected 0, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)";", 13);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* semicolon, neither label nor disk prompt exist */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ ok(!lstrcmpA(label, ""), "Expected \"\", got \"%s\"\n", label);
+ ok(labelsz == 0, "Expected 0, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, ""), "Expected \"\", got \"%s\"\n", prompt);
+ ok(promptsz == 0, "Expected 0, got %d\n", promptsz);
+
+ val = 42;
+ res = RegSetValueExA(media, "1", 0, REG_DWORD, (LPBYTE)&val, sizeof(DWORD));
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* type is REG_DWORD */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 1, "Expected 1, got %d\n", id);
+ todo_wine
+ {
+ ok(!lstrcmpA(label, "#42"), "Expected \"#42\", got \"%s\"\n", label);
+ ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "#42"), "Expected \"#42\", got \"%s\"\n", prompt);
+ ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
+ }
+
+ RegDeleteValueA(media, "1");
+ RegDeleteValueA(media, "2");
+ RegDeleteValueA(media, "4");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_USERMANAGED */
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = 0xdeadbeef;
+ lstrcpyA(prompt, "bbb");
+ promptsz = 0xdeadbeef;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
+
+ res = RegCreateKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Media key exists */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = 0xdeadbeef;
+ lstrcpyA(prompt, "bbb");
+ promptsz = 0xdeadbeef;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "2", 0, REG_SZ, (LPBYTE)"label;prompt", 13);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* disk exists, but no id 1 */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 2, "Expected 2, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ RegDeleteValueA(media, "2");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_MACHINE */
+
+ lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* machine product key exists */
+ r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_BAD_CONFIGURATION,
+ "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(prodkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = 0xdeadbeef;
+ lstrcpyA(prompt, "bbb");
+ promptsz = 0xdeadbeef;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
+
+ res = RegCreateKeyA(source, "Media", &media);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* Media key exists */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = 0xdeadbeef;
+ lstrcpyA(prompt, "bbb");
+ promptsz = 0xdeadbeef;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_NO_MORE_ITEMS,
+ "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
+
+ res = RegSetValueExA(media, "2", 0, REG_SZ, (LPBYTE)"label;prompt", 13);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* disk exists, but no id 1 */
+ id = 0;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ ok(id == 2, "Expected 2, got %d\n", id);
+ ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
+ ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
+ ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
+
+ /* szUserSid is non-NULL */
+ id = 0xbeef;
+ lstrcpyA(label, "aaa");
+ labelsz = MAX_PATH;
+ lstrcpyA(prompt, "bbb");
+ promptsz = MAX_PATH;
+ r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
+ MSICODE_PRODUCT, 0, &id, label, &labelsz,
+ prompt, &promptsz);
+ ok(r == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+ ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
+ ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
+ ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
+ ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
+ ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
+
+ RegDeleteValueA(media, "2");
+ RegDeleteKeyA(media, "");
+ RegCloseKey(media);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+}
+
+static void test_MsiSourceListAddSource(void)
+{
+ CHAR prodcode[MAX_PATH];
+ CHAR prod_squashed[MAX_PATH];
+ CHAR keypath[MAX_PATH*2];
+ CHAR username[MAX_PATH];
+ LPSTR usersid, ptr;
+ LONG res;
+ UINT r;
+ HKEY prodkey, userkey;
+ HKEY net, source;
+ DWORD size;
+
+ if (!pMsiSourceListAddSourceA)
+ {
+ skip("Skipping MsiSourceListAddSourceA tests\n");
+ return;
+ }
+
+ create_test_guid(prodcode, prod_squashed);
+ if (!get_user_sid(&usersid))
+ {
+ skip("User SID not available -> skipping MsiSourceListAddSourceA tests\n");
+ return;
+ }
+
+ /* MACHINENAME\username */
+ size = MAX_PATH;
+ GetComputerNameA(username, &size);
+ lstrcatA(username, "\\");
+ ptr = username + lstrlenA(username);
+ size = MAX_PATH;
+ GetUserNameA(ptr, &size);
+
+ /* GetLastError is not set by the function */
+
+ /* NULL szProduct */
+ r = pMsiSourceListAddSourceA(NULL, username, 0, "source");
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* empty szProduct */
+ r = pMsiSourceListAddSourceA("", username, 0, "source");
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* garbage szProduct */
+ r = pMsiSourceListAddSourceA("garbage", username, 0, "source");
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid without brackets */
+ r = pMsiSourceListAddSourceA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", username, 0, "source");
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* guid with brackets */
+ r = pMsiSourceListAddSourceA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", username, 0, "source");
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ /* dwReserved is not 0 */
+ r = pMsiSourceListAddSourceA(prodcode, username, 42, "source");
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* szSource is NULL */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, NULL);
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* szSource is empty */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "");
+ ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+
+ /* MSIINSTALLCONTEXT_USERMANAGED */
+
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
+ lstrcatA(keypath, usersid);
+ lstrcatA(keypath, "\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Net key is created */
+ res = RegOpenKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LastUsedSource does not exist and it is not created */
+ res = RegQueryValueExA(source, "LastUsedSource", 0, NULL, NULL, NULL);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ CHECK_REG_STR(net, "1", "source\\");
+
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+
+ res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"blah", 5);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LastUsedSource value exists */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Net key is created */
+ res = RegOpenKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(source, "LastUsedSource", "blah");
+ CHECK_REG_STR(net, "1", "source\\");
+
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+
+ res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"5", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LastUsedSource is an integer */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Net key is created */
+ res = RegOpenKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(source, "LastUsedSource", "5");
+ CHECK_REG_STR(net, "1", "source\\");
+
+ /* Add a second source, has trailing backslash */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "another\\");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(source, "LastUsedSource", "5");
+ CHECK_REG_STR(net, "1", "source\\");
+ CHECK_REG_STR(net, "2", "another\\");
+
+ res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"2", 2);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* LastUsedSource is in the source list */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "third/");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(source, "LastUsedSource", "2");
+ CHECK_REG_STR(net, "1", "source\\");
+ CHECK_REG_STR(net, "2", "another\\");
+ CHECK_REG_STR(net, "3", "third/\\");
+
+ RegDeleteValueA(net, "1");
+ RegDeleteValueA(net, "2");
+ RegDeleteValueA(net, "3");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_USERUNMANAGED */
+
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* user product key exists */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(userkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Net key is created */
+ res = RegOpenKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(net, "1", "source\\");
+
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(userkey, "");
+ RegCloseKey(userkey);
+
+ /* MSIINSTALLCONTEXT_MACHINE */
+
+ r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source");
+ ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
+
+ lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
+ lstrcatA(keypath, prod_squashed);
+
+ res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* machine product key exists */
+ r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source");
+ ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
+
+ res = RegCreateKeyA(prodkey, "SourceList", &source);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ /* SourceList key exists */
+ r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ /* Net key is created */
+ res = RegOpenKeyA(source, "Net", &net);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+ CHECK_REG_STR(net, "1", "source\\");
+
+ /* empty szUserName */
+ r = pMsiSourceListAddSourceA(prodcode, "", 0, "another");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+ CHECK_REG_STR(net, "1", "source\\");
+ CHECK_REG_STR(net, "2", "another\\");
+
+ RegDeleteValueA(net, "2");
+ RegDeleteValueA(net, "1");
+ RegDeleteKeyA(net, "");
+ RegCloseKey(net);
+ RegDeleteKeyA(source, "");
+ RegCloseKey(source);
+ RegDeleteKeyA(prodkey, "");
+ RegCloseKey(prodkey);
+}
+
START_TEST(source)
{
init_functionpointers();
test_MsiSourceListGetInfo();
test_MsiSourceListAddSourceEx();
+ test_MsiSourceListEnumSources();
+ test_MsiSourceListSetInfo();
+ test_MsiSourceListAddMediaDisk();
+ test_MsiSourceListEnumMediaDisks();
+ test_MsiSourceListAddSource();
}
diff --git a/rostests/winetests/msi/suminfo.c b/rostests/winetests/msi/suminfo.c
index 6ef98f7df77..3afd0d50d24 100644
--- a/rostests/winetests/msi/suminfo.c
+++ b/rostests/winetests/msi/suminfo.c
@@ -391,10 +391,11 @@ static void test_summary_binary(void)
type = 0;
r = MsiSummaryInfoGetProperty(hsuminfo, PID_LASTPRINTED, &type, NULL, NULL, sval, &sz);
ok(r == ERROR_SUCCESS, "MsiSummaryInfoGetProperty failed\n");
- ok(!strcmp(sval, ""), "Expected empty string, got %s\n", sval);
+ ok(!lstrcmpA(sval, "") || !lstrcmpA(sval, "7"),
+ "Expected empty string or \"7\", got \"%s\"\n", sval);
todo_wine {
ok(type == VT_LPSTR, "Expected VT_LPSTR, got %d\n", type);
- ok(sz == 0, "Expected 0, got %d\n", sz);
+ ok(sz == 0 || sz == 1, "Expected 0 or 1, got %d\n", sz);
}
ival = -1;
diff --git a/rostests/winetests/netapi32/access.c b/rostests/winetests/netapi32/access.c
index 3861768ef23..7d5f55a9074 100644
--- a/rostests/winetests/netapi32/access.c
+++ b/rostests/winetests/netapi32/access.c
@@ -244,7 +244,17 @@ static void run_userhandling_tests(void)
usri.usri1_password = sTestUserOldPass;
ret = pNetUserAdd(NULL, 1, (LPBYTE)&usri, NULL);
- ok(ret == NERR_BadUsername, "Adding user with too long username returned 0x%08x\n", ret);
+ if (ret == NERR_Success || ret == NERR_UserExists)
+ {
+ /* Windows NT4 does create the user. Delete the user and also if it already existed
+ * due to a previous test run on NT4.
+ */
+ trace("We are on NT4, we have to delete the user with the too long username\n");
+ ret = pNetUserDel(NULL, sTooLongName);
+ ok(ret == NERR_Success, "Deleting the user failed : %d\n", ret);
+ }
+ else
+ ok(ret == NERR_BadUsername, "Adding user with too long username returned 0x%08x\n", ret);
usri.usri1_name = sTestUserName;
usri.usri1_password = sTooLongPassword;
@@ -256,7 +266,10 @@ static void run_userhandling_tests(void)
usri.usri1_password = sTooLongPassword;
ret = pNetUserAdd(NULL, 1, (LPBYTE)&usri, NULL);
- ok(ret == NERR_BadUsername,
+ /* NT4 doesn't have a problem with the username so it will report the too long password
+ * as the error. NERR_PasswordTooShort is reported for all kind of password related errors.
+ */
+ ok(ret == NERR_BadUsername || ret == NERR_PasswordTooShort,
"Adding user with too long username/password returned 0x%08x\n", ret);
usri.usri1_name = sTestUserName;
@@ -283,7 +296,7 @@ static void run_userhandling_tests(void)
ret = pNetUserChangePassword(NULL, sNonexistentUser, sTestUserOldPass,
sTestUserNewPass);
- ok(ret == NERR_UserNotFound,
+ ok(ret == NERR_UserNotFound || ret == ERROR_INVALID_PASSWORD,
"Changing password for nonexistent user returned 0x%08x.\n", ret);
ret = pNetUserChangePassword(NULL, sTestUserName, sTestUserOldPass,
diff --git a/rostests/winetests/netapi32/netapi32.rbuild b/rostests/winetests/netapi32/netapi32.rbuild
index 1baa392a26e..42143d0bab6 100644
--- a/rostests/winetests/netapi32/netapi32.rbuild
+++ b/rostests/winetests/netapi32/netapi32.rbuild
@@ -1,17 +1,18 @@
+
.
0x600
0x600
- wine
- netapi32
- advapi32
- kernel32
- ntdll
access.c
apibuf.c
ds.c
wksta.c
testlist.c
+ wine
+ advapi32
+ kernel32
+ ntdll
+
diff --git a/rostests/winetests/netapi32/wksta.c b/rostests/winetests/netapi32/wksta.c
index ba68eb49809..5eefba4e552 100644
--- a/rostests/winetests/netapi32/wksta.c
+++ b/rostests/winetests/netapi32/wksta.c
@@ -48,7 +48,7 @@ static int init_wksta_tests(void)
BOOL rc;
user_name[0] = 0;
- dwSize = sizeof(user_name);
+ dwSize = sizeof(user_name)/sizeof(user_name[0]);
rc=GetUserNameW(user_name, &dwSize);
if (rc==FALSE && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) {
skip("GetUserNameW is not implemented\n");
@@ -57,7 +57,7 @@ static int init_wksta_tests(void)
ok(rc, "User Name Retrieved\n");
computer_name[0] = 0;
- dwSize = sizeof(computer_name);
+ dwSize = sizeof(computer_name)/sizeof(computer_name[0]);
ok(GetComputerNameW(computer_name, &dwSize), "Computer Name Retrieved\n");
return 1;
}
diff --git a/rostests/winetests/odbccp32/odbccp32.rbuild b/rostests/winetests/odbccp32/odbccp32.rbuild
index d3550a35842..3c39cc72303 100644
--- a/rostests/winetests/odbccp32/odbccp32.rbuild
+++ b/rostests/winetests/odbccp32/odbccp32.rbuild
@@ -1,14 +1,15 @@
+
.
0x600
0x600
- wine
- odbccp32
- user32
- kernel32
- ntdll
misc.c
testlist.c
+ wine
+ odbccp32
+ kernel32
+ ntdll
+
diff --git a/rostests/winetests/riched20/editor.c b/rostests/winetests/riched20/editor.c
index 48a79f52f81..090eaad0320 100644
--- a/rostests/winetests/riched20/editor.c
+++ b/rostests/winetests/riched20/editor.c
@@ -656,14 +656,60 @@ static void test_WM_GETTEXT(void)
{
HWND hwndRichEdit = new_richedit(NULL);
static const char text[] = "Hello. My name is RichEdit!";
+ static const char text2[] = "Hello. My name is RichEdit!\r";
+ static const char text2_after[] = "Hello. My name is RichEdit!\r\n";
char buffer[1024] = {0};
int result;
+ /* Baseline test with normal-sized buffer */
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text);
+ result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
+ ok(result == lstrlen(buffer),
+ "WM_GETTEXT returned %d, expected %d\n", result, lstrlen(buffer));
SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
result = strcmp(buffer,text);
ok(result == 0,
"WM_GETTEXT: settext and gettext differ. strcmp: %d\n", result);
+
+ /* Test for returned value of WM_GETTEXTLENGTH */
+ result = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
+ ok(result == lstrlen(text),
+ "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n",
+ result, lstrlen(text));
+
+ /* Test for behavior in overflow case */
+ memset(buffer, 0, 1024);
+ result = SendMessage(hwndRichEdit, WM_GETTEXT, strlen(text), (LPARAM)buffer);
+ ok(result == 0,
+ "WM_GETTEXT returned %d, expected 0\n", result);
+ result = strcmp(buffer,text);
+ ok(result == 0,
+ "WM_GETTEXT: settext and gettext differ. strcmp: %d\n", result);
+
+ /* Baseline test with normal-sized buffer and carriage return */
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text2);
+ result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
+ ok(result == lstrlen(buffer),
+ "WM_GETTEXT returned %d, expected %d\n", result, lstrlen(buffer));
+ result = strcmp(buffer,text2_after);
+ ok(result == 0,
+ "WM_GETTEXT: settext and gettext differ. strcmp: %d\n", result);
+
+ /* Test for returned value of WM_GETTEXTLENGTH */
+ result = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
+ ok(result == lstrlen(text2_after),
+ "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n",
+ result, lstrlen(text2_after));
+
+ /* Test for behavior of CRLF conversion in case of overflow */
+ memset(buffer, 0, 1024);
+ result = SendMessage(hwndRichEdit, WM_GETTEXT, strlen(text2), (LPARAM)buffer);
+ ok(result == 0,
+ "WM_GETTEXT returned %d, expected 0\n", result);
+ result = strcmp(buffer,text2);
+ ok(result == 0,
+ "WM_GETTEXT: settext and gettext differ. strcmp: %d\n", result);
+
DestroyWindow(hwndRichEdit);
}
@@ -1024,9 +1070,9 @@ static void test_WM_SETTEXT()
result = SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) a); \
ok (result == 1, "WM_SETTEXT returned %ld instead of 1\n", result); \
result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buf); \
- ok (result == strlen(buf), \
+ ok (result == lstrlen(buf), \
"WM_GETTEXT returned %ld instead of expected %u\n", \
- result, strlen(buf)); \
+ result, lstrlen(buf)); \
result = strcmp(b, buf); \
ok(result == 0, \
"WM_SETTEXT round trip: strcmp = %ld\n", result);
@@ -1116,6 +1162,33 @@ static void test_EM_SETTEXTEX(void)
ok(strcmp((const char *)buf, TestItem2_after) == 0,
"WM_GETTEXT did *not* see \\r converted to \\r\\n pairs.\n");
+ /* Baseline test for just-enough buffer space for string */
+ getText.cb = (lstrlenW(TestItem2) + 1) * sizeof(WCHAR);
+ getText.codepage = 1200; /* no constant for unicode */
+ getText.flags = GT_DEFAULT;
+ getText.lpDefaultChar = NULL;
+ getText.lpUsedDefChar = NULL;
+ memset(buf, 0, MAX_BUF_LEN);
+ SendMessage(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM) buf);
+ ok(lstrcmpW(buf, TestItem2) == 0,
+ "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
+
+ /* When there is enough space for one character, but not both, of the CRLF
+ pair at the end of the string, the CR is not copied at all. That is,
+ the caller must not see CRLF pairs truncated to CR at the end of the
+ string.
+ */
+ getText.cb = (lstrlenW(TestItem2) + 1) * sizeof(WCHAR);
+ getText.codepage = 1200; /* no constant for unicode */
+ getText.flags = GT_USECRLF; /* <-- asking for CR -> CRLF conversion */
+ getText.lpDefaultChar = NULL;
+ getText.lpUsedDefChar = NULL;
+ memset(buf, 0, MAX_BUF_LEN);
+ SendMessage(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM) buf);
+ ok(lstrcmpW(buf, TestItem1) == 0,
+ "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
+
+
/* \r\n pairs get changed into \r */
setText.codepage = 1200; /* no constant for unicode */
getText.codepage = 1200; /* no constant for unicode */
@@ -2443,8 +2516,10 @@ static void test_EM_GETTEXTLENGTHEX(void)
HWND hwnd;
GETTEXTLENGTHEX gtl;
int ret;
+ const char * base_string = "base string";
const char * test_string = "a\nb\n\n\r\n";
const char * test_string_after = "a";
+ const char * test_string_2 = "a\rtest\rstring";
char buffer[64] = {0};
/* single line */
@@ -2462,6 +2537,18 @@ static void test_EM_GETTEXTLENGTHEX(void)
ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
ok(ret == 0, "ret %d\n",ret);
+ SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM) base_string);
+
+ gtl.flags = GTL_NUMCHARS | GTL_PRECISE | GTL_USECRLF;
+ gtl.codepage = CP_ACP;
+ ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
+ ok(ret == strlen(base_string), "ret %d\n",ret);
+
+ gtl.flags = GTL_NUMCHARS | GTL_PRECISE;
+ gtl.codepage = CP_ACP;
+ ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
+ ok(ret == strlen(base_string), "ret %d\n",ret);
+
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM) test_string);
gtl.flags = GTL_NUMCHARS | GTL_PRECISE | GTL_USECRLF;
@@ -2488,19 +2575,43 @@ static void test_EM_GETTEXTLENGTHEX(void)
gtl.flags = GTL_NUMCHARS | GTL_PRECISE | GTL_USECRLF;
gtl.codepage = CP_ACP;
ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
- todo_wine ok(ret == 0, "ret %d\n",ret);
+ ok(ret == 0, "ret %d\n",ret);
gtl.flags = GTL_NUMCHARS | GTL_PRECISE;
gtl.codepage = CP_ACP;
ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
ok(ret == 0, "ret %d\n",ret);
+ SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM) base_string);
+
+ gtl.flags = GTL_NUMCHARS | GTL_PRECISE | GTL_USECRLF;
+ gtl.codepage = CP_ACP;
+ ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
+ ok(ret == strlen(base_string), "ret %d\n",ret);
+
+ gtl.flags = GTL_NUMCHARS | GTL_PRECISE;
+ gtl.codepage = CP_ACP;
+ ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
+ ok(ret == strlen(base_string), "ret %d\n",ret);
+
+ SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM) test_string_2);
+
+ gtl.flags = GTL_NUMCHARS | GTL_PRECISE | GTL_USECRLF;
+ gtl.codepage = CP_ACP;
+ ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
+ ok(ret == strlen(test_string_2) + 2, "ret %d\n",ret);
+
+ gtl.flags = GTL_NUMCHARS | GTL_PRECISE;
+ gtl.codepage = CP_ACP;
+ ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
+ ok(ret == strlen(test_string_2), "ret %d\n",ret);
+
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM) test_string);
gtl.flags = GTL_NUMCHARS | GTL_PRECISE | GTL_USECRLF;
gtl.codepage = CP_ACP;
ret = SendMessageA(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
- todo_wine ok(ret == 10, "ret %d\n",ret);
+ ok(ret == 10, "ret %d\n",ret);
gtl.flags = GTL_NUMCHARS | GTL_PRECISE;
gtl.codepage = CP_ACP;
diff --git a/rostests/winetests/riched20/riched20.rbuild b/rostests/winetests/riched20/riched20.rbuild
index f9fac8b44cf..86c225b7b2d 100644
--- a/rostests/winetests/riched20/riched20.rbuild
+++ b/rostests/winetests/riched20/riched20.rbuild
@@ -1,16 +1,17 @@
+
.
0x600
0x600
+ editor.c
+ testlist.c
wine
- riched20
ole32
user32
gdi32
kernel32
ntdll
- editor.c
- testlist.c
+
diff --git a/rostests/winetests/riched32/editor.c b/rostests/winetests/riched32/editor.c
new file mode 100644
index 00000000000..66a30909f3e
--- /dev/null
+++ b/rostests/winetests/riched32/editor.c
@@ -0,0 +1,166 @@
+/*
+* Unit test suite for rich edit control 1.0
+*
+* Copyright 2006 Google (Thomas Kho)
+* Copyright 2007 Matt Finnicum
+* Copyright 2007 Dmitry Timoshkov
+* Copyright 2007 Alex VillacÃs Lasso
+*
+* 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static HMODULE hmoduleRichEdit;
+
+static HWND new_window(LPCTSTR lpClassName, DWORD dwStyle, HWND parent) {
+ HWND hwnd;
+ hwnd = CreateWindow(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL
+ |WS_VISIBLE, 0, 0, 200, 60, parent, NULL,
+ hmoduleRichEdit, NULL);
+ ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int) GetLastError());
+ return hwnd;
+}
+
+static HWND new_richedit(HWND parent) {
+ return new_window(RICHEDIT_CLASS10A, ES_MULTILINE, parent);
+}
+
+static void test_WM_SETTEXT()
+{
+ HWND hwndRichEdit = new_richedit(NULL);
+ const char * TestItem1 = "TestSomeText";
+ const char * TestItem2 = "TestSomeText\r";
+ const char * TestItem3 = "TestSomeText\rSomeMoreText\r";
+ const char * TestItem4 = "TestSomeText\n\nTestSomeText";
+ const char * TestItem5 = "TestSomeText\r\r\nTestSomeText";
+ const char * TestItem6 = "TestSomeText\r\r\n\rTestSomeText";
+ const char * TestItem7 = "TestSomeText\r\n\r\r\n\rTestSomeText";
+ const char * TestItem8 = "TestSomeText\r\n";
+ const char * TestItem9 = "TestSomeText\r\nSomeMoreText\r\n";
+ const char * TestItem10 = "TestSomeText\r\n\r\nTestSomeText";
+ const char * TestItem11 = "TestSomeText TestSomeText";
+ const char * TestItem12 = "TestSomeText \r\nTestSomeText";
+ const char * TestItem13 = "TestSomeText\r\n \r\nTestSomeText";
+ char buf[1024] = {0};
+ LRESULT result;
+
+ /* This test attempts to show that WM_SETTEXT on a riched32 control does not
+ attempt to modify the text that is pasted into the control, and should
+ return it as is. In particular, \r\r\n is NOT converted, unlike riched20.
+ Currently, builtin riched32 mangles solitary \r or \n when not part of
+ a \r\n pair.
+ */
+
+#define TEST_SETTEXT(a, b, is_todo) \
+ result = SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) a); \
+ ok (result == 1, "WM_SETTEXT returned %ld instead of 1\n", result); \
+ result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buf); \
+ ok (result == lstrlen(buf), \
+ "WM_GETTEXT returned %ld instead of expected %u\n", \
+ result, lstrlen(buf)); \
+ result = strcmp(b, buf); \
+ if (is_todo) todo_wine { \
+ ok(result == 0, \
+ "WM_SETTEXT round trip: strcmp = %ld\n", result); \
+ } else { \
+ ok(result == 0, \
+ "WM_SETTEXT round trip: strcmp = %ld\n", result); \
+ }
+
+ TEST_SETTEXT(TestItem1, TestItem1, 0)
+ TEST_SETTEXT(TestItem2, TestItem2, 1)
+ TEST_SETTEXT(TestItem3, TestItem3, 1)
+ TEST_SETTEXT(TestItem4, TestItem4, 1)
+ TEST_SETTEXT(TestItem5, TestItem5, 1)
+ TEST_SETTEXT(TestItem6, TestItem6, 1)
+ TEST_SETTEXT(TestItem7, TestItem7, 1)
+ TEST_SETTEXT(TestItem8, TestItem8, 0)
+ TEST_SETTEXT(TestItem9, TestItem9, 0)
+ TEST_SETTEXT(TestItem10, TestItem10, 0)
+ TEST_SETTEXT(TestItem11, TestItem11, 0)
+ TEST_SETTEXT(TestItem12, TestItem12, 0)
+ TEST_SETTEXT(TestItem13, TestItem13, 0)
+
+#undef TEST_SETTEXT
+ DestroyWindow(hwndRichEdit);
+}
+
+static void test_WM_GETTEXTLENGTH(void)
+{
+ HWND hwndRichEdit = new_richedit(NULL);
+ static const char text3[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee";
+ static const char text4[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee\r\n";
+ int result;
+
+ /* Test for WM_GETTEXTLENGTH */
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text3);
+ result = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
+ ok(result == lstrlen(text3),
+ "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n",
+ result, lstrlen(text3));
+
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text4);
+ result = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
+ ok(result == lstrlen(text4),
+ "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n",
+ result, lstrlen(text4));
+
+ DestroyWindow(hwndRichEdit);
+}
+
+START_TEST( editor )
+{
+ MSG msg;
+ time_t end;
+
+ /* Must explicitly LoadLibrary(). The test has no references to functions in
+ * RICHED32.DLL, so the linker doesn't actually link to it. */
+ hmoduleRichEdit = LoadLibrary("RICHED32.DLL");
+ ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
+
+ test_WM_SETTEXT();
+ test_WM_GETTEXTLENGTH();
+
+ /* Set the environment variable WINETEST_RICHED32 to keep windows
+ * responsive and open for 30 seconds. This is useful for debugging.
+ *
+ * The message pump uses PeekMessage() to empty the queue and then sleeps for
+ * 50ms before retrying the queue. */
+ end = time(NULL) + 30;
+ if (getenv( "WINETEST_RICHED32" )) {
+ while (time(NULL) < end) {
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ } else {
+ Sleep(50);
+ }
+ }
+ }
+
+ OleFlushClipboard();
+ ok(FreeLibrary(hmoduleRichEdit) != 0, "error: %d\n", (int) GetLastError());
+}
diff --git a/rostests/winetests/riched32/riched32.rbuild b/rostests/winetests/riched32/riched32.rbuild
new file mode 100644
index 00000000000..4c328a2301f
--- /dev/null
+++ b/rostests/winetests/riched32/riched32.rbuild
@@ -0,0 +1,16 @@
+
+
+
+
+ .
+ 0x600
+ 0x600
+ editor.c
+ testlist.c
+ wine
+ ole32
+ user32
+ kernel32
+ ntdll
+
+
diff --git a/rostests/winetests/riched32/testlist.c b/rostests/winetests/riched32/testlist.c
new file mode 100644
index 00000000000..08e717eeb0d
--- /dev/null
+++ b/rostests/winetests/riched32/testlist.c
@@ -0,0 +1,15 @@
+/* Automatically generated file; DO NOT EDIT!! */
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+#define STANDALONE
+#include "wine/test.h"
+
+extern void func_editor(void);
+
+const struct test winetest_testlist[] =
+{
+ { "editor", func_editor },
+ { 0, 0 }
+};
diff --git a/rostests/winetests/rsaenh/rsaenh.c b/rostests/winetests/rsaenh/rsaenh.c
index 5a7b47422c9..4fef6e9fb5b 100644
--- a/rostests/winetests/rsaenh/rsaenh.c
+++ b/rostests/winetests/rsaenh/rsaenh.c
@@ -175,12 +175,20 @@ static void test_prov(void)
DWORD dwLen, dwInc;
dwLen = (DWORD)sizeof(DWORD);
+ SetLastError(0xdeadbeef);
result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
- ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
+ if (!result && GetLastError() == NTE_BAD_TYPE)
+ skip("PP_SIG_KEYSIZE_INC is not supported (win9x or NT)\n");
+ else
+ ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
dwLen = (DWORD)sizeof(DWORD);
+ SetLastError(0xdeadbeef);
result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
- ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
+ if (!result && GetLastError() == NTE_BAD_TYPE)
+ skip("PP_KEYX_KEYSIZE_INC is not supported (win9x or NT)\n");
+ else
+ ok(result && dwInc==8, "%08x, %d\n", GetLastError(), dwInc);
}
static void test_gen_random(void)
@@ -1823,9 +1831,13 @@ static void test_null_provider(void)
ok(result && dataLen == sizeof(dwParam) && (dwParam & CRYPT_SEC_DESCR),
"Expected CRYPT_SEC_DESCR to be set, got 0x%08X\n",dwParam);
dataLen = sizeof(keySpec);
+ SetLastError(0xdeadbeef);
result = CryptGetProvParam(prov, PP_KEYSPEC, (LPBYTE)&keySpec, &dataLen, 0);
- ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
- "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
+ if (!result && GetLastError() == NTE_BAD_TYPE)
+ skip("PP_KEYSPEC is not supported (win9x or NT)\n");
+ else
+ ok(result && keySpec == (AT_KEYEXCHANGE | AT_SIGNATURE),
+ "Expected AT_KEYEXCHANGE | AT_SIGNATURE, got %08x\n", keySpec);
/* PP_CONTAINER parameter */
dataLen = sizeof(szName);
result = CryptGetProvParam(prov, PP_CONTAINER, (LPBYTE)szName, &dataLen, 0);
@@ -1834,10 +1846,14 @@ static void test_null_provider(void)
(result)? "TRUE":"FALSE",GetLastError(),dataLen);
/* PP_UNIQUE_CONTAINER parameter */
dataLen = sizeof(szName);
+ SetLastError(0xdeadbeef);
result = CryptGetProvParam(prov, PP_UNIQUE_CONTAINER, (LPBYTE)szName, &dataLen, 0);
- ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
- "failed getting PP_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
- (result)? "TRUE":"FALSE",GetLastError(),dataLen);
+ if (!result && GetLastError() == NTE_BAD_TYPE)
+ skip("PP_UNIQUE_CONTAINER is not supported (win9x or NT)\n");
+ else
+ ok(result && dataLen == strlen(szContainer)+1 && strcmp(szContainer,szName) == 0,
+ "failed getting PP_UNIQUE_CONTAINER. result = %s. Error 0x%08X. returned length = %d\n",
+ (result)? "TRUE":"FALSE",GetLastError(),dataLen);
result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key);
ok(!result && GetLastError() == NTE_NO_KEY,
"Expected NTE_NO_KEY, got %08x\n", GetLastError());
diff --git a/rostests/winetests/rsaenh/rsaenh.rbuild b/rostests/winetests/rsaenh/rsaenh.rbuild
index f8f3ad2f317..94d58ac95b8 100644
--- a/rostests/winetests/rsaenh/rsaenh.rbuild
+++ b/rostests/winetests/rsaenh/rsaenh.rbuild
@@ -5,11 +5,11 @@
.
0x600
0x600
+ rsaenh.c
+ testlist.c
wine
advapi32
kernel32
ntdll
- rsaenh.c
- testlist.c
diff --git a/rostests/winetests/shlwapi/generated.c b/rostests/winetests/shlwapi/generated.c
index d1bfa4c8200..6d50fbcf32e 100755
--- a/rostests/winetests/shlwapi/generated.c
+++ b/rostests/winetests/shlwapi/generated.c
@@ -21,7 +21,7 @@
#include "wine/test.h"
/***********************************************************************
- * Compability macros
+ * Compatibility macros
*/
#define DWORD_PTR UINT_PTR
diff --git a/rostests/winetests/shlwapi/istream.c b/rostests/winetests/shlwapi/istream.c
new file mode 100644
index 00000000000..7172e31f764
--- /dev/null
+++ b/rostests/winetests/shlwapi/istream.c
@@ -0,0 +1,577 @@
+/* Unit test suite for SHLWAPI ShCreateStreamOnFile functions.
+ *
+ * Copyright 2008 Reece H. Dunn
+ *
+ * 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
+ */
+
+#define COBJMACROS
+
+#include
+#include
+
+#include "wine/test.h"
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "shlwapi.h"
+
+
+/* Function pointers for the SHCreateStreamOnFile functions */
+static HMODULE hShlwapi;
+static HRESULT (WINAPI *pSHCreateStreamOnFileA)(LPCSTR file, DWORD mode, IStream **stream);
+static HRESULT (WINAPI *pSHCreateStreamOnFileW)(LPCWSTR file, DWORD mode, IStream **stream);
+static HRESULT (WINAPI *pSHCreateStreamOnFileEx)(LPCWSTR file, DWORD mode, DWORD attributes, BOOL create, IStream *template, IStream **stream);
+
+
+static void test_IStream_invalid_operations(IStream * stream, DWORD mode)
+{
+ HRESULT ret;
+ IStream * clone;
+ ULONG refcount;
+ ULARGE_INTEGER uzero;
+ ULARGE_INTEGER uret;
+ LARGE_INTEGER zero;
+ ULONG count;
+ char data[256];
+
+ U(uzero).HighPart = 0;
+ U(uzero).LowPart = 0;
+ U(uret).HighPart = 0;
+ U(uret).LowPart = 0;
+ U(zero).HighPart = 0;
+ U(zero).LowPart = 0;
+
+ /* IStream::Read */
+
+ /* IStream_Read from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Read helper function. */
+
+ ret = stream->lpVtbl->Read(stream, NULL, 0, &count);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ ret = stream->lpVtbl->Read(stream, data, 5, NULL);
+ ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08x\n", ret);
+
+ ret = stream->lpVtbl->Read(stream, data, 0, NULL);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ ret = stream->lpVtbl->Read(stream, data, 3, &count);
+ ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08x\n", ret);
+
+ /* IStream::Write */
+
+ /* IStream_Write from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Write helper function. */
+
+ ret = stream->lpVtbl->Write(stream, NULL, 0, &count);
+ if (mode == STGM_READ)
+ ok(ret == STG_E_ACCESSDENIED, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
+ else
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ strcpy(data, "Hello");
+ ret = stream->lpVtbl->Write(stream, data, 5, NULL);
+ if (mode == STGM_READ)
+ ok(ret == STG_E_ACCESSDENIED, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
+ else
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ strcpy(data, "Hello");
+ ret = stream->lpVtbl->Write(stream, data, 0, NULL);
+ if (mode == STGM_READ)
+ ok(ret == STG_E_ACCESSDENIED, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
+ else
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ strcpy(data, "Hello");
+ ret = stream->lpVtbl->Write(stream, data, 0, &count);
+ if (mode == STGM_READ)
+ ok(ret == STG_E_ACCESSDENIED, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
+ else
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ strcpy(data, "Hello");
+ ret = stream->lpVtbl->Write(stream, data, 3, &count);
+ if (mode == STGM_READ)
+ ok(ret == STG_E_ACCESSDENIED, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
+ else
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ /* IStream::Seek */
+
+ ret = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ ret = IStream_Seek(stream, zero, 20, NULL);
+ ok(ret == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", ret);
+
+ /* IStream::CopyTo */
+
+ ret = IStream_CopyTo(stream, NULL, uzero, &uret, &uret);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ clone = NULL;
+ ret = IStream_CopyTo(stream, clone, uzero, &uret, &uret);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ ret = IStream_CopyTo(stream, stream, uzero, &uret, &uret);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ ret = IStream_CopyTo(stream, stream, uzero, &uret, NULL);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ ret = IStream_CopyTo(stream, stream, uzero, NULL, &uret);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ /* IStream::Commit */
+
+ ret = IStream_Commit(stream, STGC_DEFAULT);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ /* IStream::Revert */
+
+ ret = IStream_Revert(stream);
+ ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret);
+
+ /* IStream::LockRegion */
+
+ ret = IStream_LockRegion(stream, uzero, uzero, 0);
+ ok(ret == E_NOTIMPL /* XP */ || ret == S_OK /* Vista */,
+ "expected E_NOTIMPL or S_OK, got 0x%08x\n", ret);
+
+ /* IStream::UnlockRegion */
+
+ if (ret == E_NOTIMPL) /* XP */ {
+ ret = IStream_UnlockRegion(stream, uzero, uzero, 0);
+ ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret);
+ } else /* Vista */ {
+ ret = IStream_UnlockRegion(stream, uzero, uzero, 0);
+ ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);
+
+ ret = IStream_UnlockRegion(stream, uzero, uzero, 0);
+ ok(ret == STG_E_LOCKVIOLATION, "expected STG_E_LOCKVIOLATION, got 0x%08x\n", ret);
+ }
+
+ /* IStream::Stat */
+
+ ret = IStream_Stat(stream, NULL, 0);
+ ok(ret == STG_E_INVALIDPOINTER, "expected STG_E_INVALIDPOINTER, got 0x%08x\n", ret);
+
+ /* IStream::Clone */
+
+ ret = IStream_Clone(stream, NULL);
+ ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret);
+
+ clone = NULL;
+ ret = IStream_Clone(stream, &clone);
+ ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret);
+ ok(clone == NULL, "expected a NULL IStream object, got %p\n", stream);
+
+ if (clone) {
+ refcount = IStream_Release(clone);
+ ok(refcount == 0, "expected 0, got %d\n", refcount);
+ }
+}
+
+
+static void test_SHCreateStreamOnFileA(DWORD mode)
+{
+ IStream * stream;
+ HRESULT ret;
+ ULONG refcount;
+ static const char * test_file = "c:\\test.txt";
+
+ trace("SHCreateStreamOnFileA: testing mode %d\n", mode);
+
+ /* invalid arguments */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(NULL, mode, &stream);
+ todo_wine
+ ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream);
+
+#if 0 /* This test crashes on WinXP SP2 */
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode, NULL);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret);
+#endif
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode | STGM_CONVERT, &stream);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode | STGM_DELETEONRELEASE, &stream);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode | STGM_TRANSACTED, &stream);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream);
+
+ /* file does not exist */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode | STGM_FAILIFTHERE, &stream);
+ todo_wine
+ ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode | STGM_CREATE, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount);
+ }
+
+ /* NOTE: don't delete the file, as it will be used for the file exists tests. */
+
+ /* file exists */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode | STGM_FAILIFTHERE, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount);
+ }
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileA)(test_file, mode | STGM_CREATE, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount);
+
+ ok(DeleteFileA(test_file), "SHCreateStreamOnFileA: could not delete file '%s', got error %d\n", test_file, GetLastError());
+ }
+}
+
+
+static void test_SHCreateStreamOnFileW(DWORD mode)
+{
+ IStream * stream;
+ HRESULT ret;
+ ULONG refcount;
+ static const WCHAR test_file[] = { 'c', ':', '\\', 't', 'e', 's', 't', '.', 't', 'x', 't', '\0' };
+
+ trace("SHCreateStreamOnFileW: testing mode %d\n", mode);
+
+ /* invalid arguments */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(NULL, mode, &stream);
+ ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* XP */
+ ret == E_INVALIDARG /* Vista */,
+ "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream);
+
+#if 0 /* This test crashes on WinXP SP2 */
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode, NULL);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret);
+#endif
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_CONVERT, &stream);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_DELETEONRELEASE, &stream);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_TRANSACTED, &stream);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream);
+
+ /* file does not exist */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_FAILIFTHERE, &stream);
+ todo_wine
+ ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_CREATE, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount);
+ }
+
+ /* NOTE: don't delete the file, as it will be used for the file exists tests. */
+
+ /* file exists */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_FAILIFTHERE, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount);
+ }
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_CREATE, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount);
+
+ ok(DeleteFileW(test_file), "SHCreateStreamOnFileW: could not delete the test file, got error %d\n", GetLastError());
+ }
+}
+
+
+static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm)
+{
+ IStream * stream;
+ IStream * template = NULL;
+ HRESULT ret;
+ ULONG refcount;
+ static const WCHAR test_file[] = { 'c', ':', '\\', 't', 'e', 's', 't', '.', 't', 'x', 't', '\0' };
+
+ trace("SHCreateStreamOnFileEx: testing mode %d, STGM flags %08x\n", mode, stgm);
+
+ /* invalid arguments */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(NULL, mode, 0, FALSE, NULL, &stream);
+ ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* XP */
+ ret == E_INVALIDARG /* Vista */,
+ "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode, 0, FALSE, template, &stream);
+ todo_wine
+ ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream);
+
+#if 0 /* This test crashes on WinXP SP2 */
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode, 0, FALSE, NULL, NULL);
+ ok(ret == E_INVALIDARG, "SHCreateStreamOnFileEx: expected E_INVALIDARG, got 0x%08x\n", ret);
+#endif
+
+ /* file does not exist */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_FAILIFTHERE | stgm, 0, FALSE, NULL, &stream);
+ if ((stgm & STGM_TRANSACTED) == STGM_TRANSACTED && mode == STGM_READ) {
+ ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* XP */ || ret == E_INVALIDARG /* Vista */,
+ "SHCreateStreamOnFileEx: expected E_INVALIDARG or HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret);
+
+ if (ret == E_INVALIDARG) {
+ skip("SHCreateStreamOnFileEx: STGM_TRANSACTED not supported in this configuration.\n");
+ return;
+ }
+ } else {
+ todo_wine
+ ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret);
+ }
+ ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_FAILIFTHERE | stgm, 0, TRUE, NULL, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount);
+
+ ok(DeleteFileW(test_file), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
+ }
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, FALSE, NULL, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount);
+
+ ok(DeleteFileW(test_file), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
+ }
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, TRUE, NULL, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount);
+ }
+
+ /* NOTE: don't delete the file, as it will be used for the file exists tests. */
+
+ /* file exists */
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_FAILIFTHERE | stgm, 0, FALSE, NULL, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount);
+ }
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_FAILIFTHERE | stgm, 0, TRUE, NULL, &stream);
+ todo_wine
+ ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), got 0x%08x\n", ret);
+ ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream);
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, FALSE, NULL, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount);
+ }
+
+ stream = NULL;
+ ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, TRUE, NULL, &stream);
+ todo_wine
+ ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret);
+ todo_wine
+ ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
+
+ if (stream) {
+ test_IStream_invalid_operations(stream, mode);
+
+ refcount = IStream_Release(stream);
+ ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount);
+ }
+
+ todo_wine
+ ok(DeleteFileW(test_file), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
+}
+
+
+START_TEST(istream)
+{
+ static const DWORD stgm_access[] = {
+ STGM_READ,
+ STGM_WRITE,
+ STGM_READWRITE
+ };
+
+ static const DWORD stgm_flags[] = {
+ 0,
+ STGM_CONVERT,
+ STGM_DELETEONRELEASE,
+ STGM_CONVERT | STGM_DELETEONRELEASE,
+ STGM_TRANSACTED | STGM_CONVERT,
+ STGM_TRANSACTED | STGM_DELETEONRELEASE,
+ STGM_TRANSACTED | STGM_CONVERT | STGM_DELETEONRELEASE
+ };
+
+ int i, j;
+
+ hShlwapi = GetModuleHandleA("shlwapi.dll");
+
+ pSHCreateStreamOnFileA = (void*)GetProcAddress(hShlwapi, "SHCreateStreamOnFileA");
+ pSHCreateStreamOnFileW = (void*)GetProcAddress(hShlwapi, "SHCreateStreamOnFileW");
+ pSHCreateStreamOnFileEx = (void*)GetProcAddress(hShlwapi, "SHCreateStreamOnFileEx");
+
+ if (!pSHCreateStreamOnFileA)
+ skip("SHCreateStreamOnFileA not found.\n");
+
+ if (!pSHCreateStreamOnFileW)
+ skip("SHCreateStreamOnFileW not found.\n");
+
+ if (!pSHCreateStreamOnFileEx)
+ skip("SHCreateStreamOnFileEx not found.\n");
+
+ for (i = 0; i != sizeof(stgm_access)/sizeof(stgm_access[0]); i++) {
+ if (pSHCreateStreamOnFileA)
+ test_SHCreateStreamOnFileA(stgm_access[i]);
+
+ if (pSHCreateStreamOnFileW)
+ test_SHCreateStreamOnFileW(stgm_access[i]);
+
+ if (pSHCreateStreamOnFileEx) {
+ for (j = 0; j != sizeof(stgm_flags)/sizeof(stgm_flags[0]); j++)
+ test_SHCreateStreamOnFileEx(stgm_access[i], stgm_flags[j]);
+ }
+ }
+}
diff --git a/rostests/winetests/shlwapi/path.c b/rostests/winetests/shlwapi/path.c
index 5fb490d0fad..b2d2a9ea7b1 100755
--- a/rostests/winetests/shlwapi/path.c
+++ b/rostests/winetests/shlwapi/path.c
@@ -76,11 +76,13 @@ static struct {
} TEST_PATH_IS_URL[] = {
{"http://foo/bar", TRUE},
{"c:\\foo\\bar", FALSE},
+ {"c:/foo/bar", FALSE},
{"foo://foo/bar", TRUE},
{"foo\\bar", FALSE},
{"foo.bar", FALSE},
{"bogusscheme:", TRUE},
- {"http:partial", TRUE}
+ {"http:partial", TRUE},
+ {"www.winehq.org", FALSE}
};
struct {
@@ -906,9 +908,9 @@ static void test_PathCanonicalizeA(void)
lstrcpy(dest, "test");
SetLastError(0xdeadbeef);
res = PathCanonicalizeA(dest, too_long);
+ ok(!res, "Expected failure\n");
todo_wine
{
- ok(!res, "Expected failure\n");
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
}
ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
diff --git a/rostests/winetests/shlwapi/shlwapi.rbuild b/rostests/winetests/shlwapi/shlwapi.rbuild
index 205175e03ef..f6d735e0b63 100644
--- a/rostests/winetests/shlwapi/shlwapi.rbuild
+++ b/rostests/winetests/shlwapi/shlwapi.rbuild
@@ -5,6 +5,16 @@
.
0x600
0x600
+ clist.c
+ clsid.c
+ generated.c
+ istream.c
+ ordinal.c
+ path.c
+ shreg.c
+ string.c
+ url.c
+ testlist.c
wine
shlwapi
advapi32
@@ -13,14 +23,5 @@
kernel32
uuid
ntdll
- clist.c
- clsid.c
- generated.c
- ordinal.c
- path.c
- shreg.c
- string.c
- url.c
- testlist.c
diff --git a/rostests/winetests/shlwapi/string.c b/rostests/winetests/shlwapi/string.c
index b90dcc630cc..0b4f28ba29e 100755
--- a/rostests/winetests/shlwapi/string.c
+++ b/rostests/winetests/shlwapi/string.c
@@ -35,16 +35,24 @@
ok(ret == val, "Unexpected value of '" #expr "': " #fmt " instead of " #val "\n", ret); \
} while (0);
-static HMODULE hShlwapi;
-static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int);
-static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int);
-static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,void*,BSTR*);
+static BOOL (WINAPI *pIntlStrEqWorkerA)(BOOL,LPCSTR,LPCSTR,int);
+static BOOL (WINAPI *pIntlStrEqWorkerW)(BOOL,LPCWSTR,LPCWSTR,int);
static DWORD (WINAPI *pSHAnsiToAnsi)(LPCSTR,LPSTR,int);
static DWORD (WINAPI *pSHUnicodeToUnicode)(LPCWSTR,LPWSTR,int);
+static LPSTR (WINAPI *pStrCatBuffA)(LPSTR,LPCSTR,INT);
+static LPWSTR (WINAPI *pStrCatBuffW)(LPWSTR,LPCWSTR,INT);
+static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int);
+static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int);
+static LPSTR (WINAPI *pStrFormatByteSize64A)(LONGLONG,LPSTR,UINT);
+static LPSTR (WINAPI *pStrFormatKBSizeA)(LONGLONG,LPSTR,UINT);
+static LPWSTR (WINAPI *pStrFormatKBSizeW)(LONGLONG,LPWSTR,UINT);
static BOOL (WINAPI *pStrIsIntlEqualA)(BOOL,LPCSTR,LPCSTR,int);
-static BOOL (WINAPI *pIntlStrEqWorkerA)(BOOL,LPCSTR,LPCSTR,int);
static BOOL (WINAPI *pStrIsIntlEqualW)(BOOL,LPCWSTR,LPCWSTR,int);
-static BOOL (WINAPI *pIntlStrEqWorkerW)(BOOL,LPCWSTR,LPCWSTR,int);
+static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,void*,BSTR*);
+static HRESULT (WINAPI *pStrRetToBufA)(STRRET*,LPCITEMIDLIST,LPSTR,UINT);
+static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
+static INT (WINAPIV *pwnsprintfA)(LPSTR,INT,LPCSTR, ...);
+static INT (WINAPIV *pwnsprintfW)(LPWSTR,INT,LPCWSTR, ...);
static int strcmpW(const WCHAR *str1, const WCHAR *str2)
{
@@ -491,9 +499,15 @@ static void test_StrFormatByteSize64A(void)
char szBuff[256];
const StrFormatSizeResult* result = StrFormatSize_results;
+ if (!pStrFormatByteSize64A)
+ {
+ skip("StrFormatByteSize64A() is not available. Tests skipped\n");
+ return;
+ }
+
while(result->value)
{
- StrFormatByteSize64A(result->value, szBuff, 256);
+ pStrFormatByteSize64A(result->value, szBuff, 256);
ok(!strcmp(result->byte_size_64, szBuff),
"Formatted %x%08x wrong: got %s, expected %s\n",
@@ -509,9 +523,15 @@ static void test_StrFormatKBSizeW(void)
char szBuff[256];
const StrFormatSizeResult* result = StrFormatSize_results;
+ if (!pStrFormatKBSizeW)
+ {
+ skip("StrFormatKBSizeW() is not available. Tests skipped\n");
+ return;
+ }
+
while(result->value)
{
- StrFormatKBSizeW(result->value, szBuffW, 256);
+ pStrFormatKBSizeW(result->value, szBuffW, 256);
WideCharToMultiByte(0,0,szBuffW,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR),0,0);
ok(!strcmp(result->kb_size, szBuff),
"Formatted %x%08x wrong: got %s, expected %s\n",
@@ -525,9 +545,15 @@ static void test_StrFormatKBSizeA(void)
char szBuff[256];
const StrFormatSizeResult* result = StrFormatSize_results;
+ if (!pStrFormatKBSizeA)
+ {
+ skip("StrFormatKBSizeA() is not available. Tests skipped\n");
+ return;
+ }
+
while(result->value)
{
- StrFormatKBSizeA(result->value, szBuff, 256);
+ pStrFormatKBSizeA(result->value, szBuff, 256);
ok(!strcmp(result->kb_size, szBuff),
"Formatted %x%08x wrong: got %s, expected %s\n",
@@ -561,20 +587,21 @@ static void test_StrCmpA(void)
ok(!ChrCmpIA('b', 'B'), "ChrCmpIA is not case-insensitive\n");
ok(ChrCmpIA('a', 'z'), "ChrCmpIA believes that a == z!\n");
- pStrIsIntlEqualA = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualA");
- pIntlStrEqWorkerA = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerA");
+ if (pStrIsIntlEqualA)
+ {
+ ok(pStrIsIntlEqualA(FALSE, str1, str2, 5), "StrIsIntlEqualA(FALSE,...) isn't case-insensitive\n");
+ ok(!pStrIsIntlEqualA(TRUE, str1, str2, 5), "StrIsIntlEqualA(TRUE,...) isn't case-sensitive\n");
+ }
+ else
+ skip("StrIsIntlEqualA() is not available. Tests skipped\n");
- if (!pStrIsIntlEqualA)
- return;
-
- ok(pStrIsIntlEqualA(FALSE, str1, str2, 5), "StrIsIntlEqualA(FALSE,...) isn't case-insensitive\n");
- ok(!pStrIsIntlEqualA(TRUE, str1, str2, 5), "StrIsIntlEqualA(TRUE,...) isn't case-sensitive\n");
-
- if (!pIntlStrEqWorkerA)
- return;
-
- ok(pIntlStrEqWorkerA(FALSE, str1, str2, 5), "IntlStrEqWorkerA(FALSE,...) isn't case-insensitive\n");
- ok(!pIntlStrEqWorkerA(TRUE, str1, str2, 5), "pIntlStrEqWorkerA(TRUE,...) isn't case-sensitive\n");
+ if (pIntlStrEqWorkerA)
+ {
+ ok(pIntlStrEqWorkerA(FALSE, str1, str2, 5), "IntlStrEqWorkerA(FALSE,...) isn't case-insensitive\n");
+ ok(!pIntlStrEqWorkerA(TRUE, str1, str2, 5), "pIntlStrEqWorkerA(TRUE,...) isn't case-sensitive\n");
+ }
+ else
+ skip("IntlStrEqWorkerA() is not available. Tests skipped\n");
}
static void test_StrCmpW(void)
@@ -587,20 +614,21 @@ static void test_StrCmpW(void)
ok(!ChrCmpIW('b', 'B'), "ChrCmpIW is not case-insensitive\n");
ok(ChrCmpIW('a', 'z'), "ChrCmpIW believes that a == z!\n");
- pStrIsIntlEqualW = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualW");
- pIntlStrEqWorkerW = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerW");
+ if (pStrIsIntlEqualW)
+ {
+ ok(pStrIsIntlEqualW(FALSE, str1, str2, 5), "StrIsIntlEqualW(FALSE,...) isn't case-insensitive\n");
+ ok(!pStrIsIntlEqualW(TRUE, str1, str2, 5), "StrIsIntlEqualW(TRUE,...) isn't case-sensitive\n");
+ }
+ else
+ skip("StrIsIntlEqualW() is not available. Tests skipped\n");
- if (!pStrIsIntlEqualW)
- return;
-
- ok(pStrIsIntlEqualW(FALSE, str1, str2, 5), "StrIsIntlEqualW(FALSE,...) isn't case-insensitive\n");
- ok(!pStrIsIntlEqualW(TRUE, str1, str2, 5), "StrIsIntlEqualW(TRUE,...) isn't case-sensitive\n");
-
- if (!pIntlStrEqWorkerW)
- return;
-
- ok(pIntlStrEqWorkerW(FALSE, str1, str2, 5), "IntlStrEqWorkerW(FALSE,...) isn't case-insensitive\n");
- ok(!pIntlStrEqWorkerW(TRUE, str1, str2, 5), "IntlStrEqWorkerW(TRUE,...) isn't case-sensitive\n");
+ if (pIntlStrEqWorkerW)
+ {
+ ok(pIntlStrEqWorkerW(FALSE, str1, str2, 5), "IntlStrEqWorkerW(FALSE,...) isn't case-insensitive\n");
+ ok(!pIntlStrEqWorkerW(TRUE, str1, str2, 5), "IntlStrEqWorkerW(TRUE,...) isn't case-sensitive\n");
+ }
+ else
+ skip("IntlStrEqWorkerW() is not available. Tests skipped\n");
}
static WCHAR *CoDupStrW(const char* src)
@@ -619,8 +647,11 @@ static void test_StrRetToBSTR(void)
STRRET strret;
HRESULT ret;
- pStrRetToBSTR = (void *)GetProcAddress(hShlwapi, "StrRetToBSTR");
- if (!pStrRetToBSTR) return;
+ if (!pStrRetToBSTR)
+ {
+ skip("StrRetToBSTR() is not available. Tests skipped\n");
+ return;
+ }
strret.uType = STRRET_WSTR;
U(strret).pOleStr = CoDupStrW("Test");
@@ -657,9 +688,11 @@ static void test_StrCpyNXA(void)
LPSTR lpszRes;
char dest[8];
- pStrCpyNXA = (void *)GetProcAddress(hShlwapi, (LPSTR)399);
if (!pStrCpyNXA)
+ {
+ skip("StrCpyNXA() is not available. Tests skipped\n");
return;
+ }
memset(dest, '\n', sizeof(dest));
lpszRes = pStrCpyNXA(dest, lpSrc, sizeof(dest)/sizeof(dest[0]));
@@ -676,14 +709,16 @@ static void test_StrCpyNXW(void)
LPWSTR lpszRes;
WCHAR dest[8];
- pStrCpyNXW = (void *)GetProcAddress(hShlwapi, (LPSTR)400);
if (!pStrCpyNXW)
+ {
+ skip("StrCpyNXW() is not available. Tests skipped\n");
return;
+ }
memcpy(dest, lpInit, sizeof(lpInit));
lpszRes = pStrCpyNXW(dest, lpSrc, sizeof(dest)/sizeof(dest[0]));
ok(lpszRes == dest + 5 && !memcmp(dest, lpRes, sizeof(dest)),
- "StrCpyNXA: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
+ "StrCpyNXW: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
@@ -731,9 +766,11 @@ static void test_SHAnsiToAnsi(void)
char dest[8];
DWORD dwRet;
- pSHAnsiToAnsi = (void *)GetProcAddress(hShlwapi, (LPSTR)345);
if (!pSHAnsiToAnsi)
+ {
+ skip("SHAnsiToAnsi() is not available. Tests skipped\n");
return;
+ }
memset(dest, '\n', sizeof(dest));
dwRet = pSHAnsiToAnsi("hello", dest, sizeof(dest)/sizeof(dest[0]));
@@ -750,9 +787,11 @@ static void test_SHUnicodeToUnicode(void)
WCHAR dest[8];
DWORD dwRet;
- pSHUnicodeToUnicode = (void *)GetProcAddress(hShlwapi, (LPSTR)346);
if (!pSHUnicodeToUnicode)
+ {
+ skip("SHUnicodeToUnicode() is not available. Tests skipped\n");
return;
+ }
memcpy(dest, lpInit, sizeof(lpInit));
dwRet = pSHUnicodeToUnicode(lpSrc, dest, sizeof(dest)/sizeof(dest[0]));
@@ -782,46 +821,80 @@ static void test_StrXXX_overflows(void)
expect_eq(StrCpyNA(buf, str1, 10), buf, PCHAR, "%p");
expect_eq(buf[9], 0, CHAR, "%x");
expect_eq(buf[10], '\xbf', CHAR, "%x");
- expect_eq(StrCatBuffA(buf, str1, 100), buf, PCHAR, "%p");
- expect_eq(buf[99], 0, CHAR, "%x");
- expect_eq(buf[100], '\xbf', CHAR, "%x");
+
+ if (pStrCatBuffA)
+ {
+ expect_eq(pStrCatBuffA(buf, str1, 100), buf, PCHAR, "%p");
+ expect_eq(buf[99], 0, CHAR, "%x");
+ expect_eq(buf[100], '\xbf', CHAR, "%x");
+ }
+ else
+ skip("StrCatBuffA() is not available. Tests skipped\n");
memset(wbuf, 0xbf, sizeof(wbuf));
expect_eq(StrCpyNW(wbuf, wstr1, 10), wbuf, PWCHAR, "%p");
expect_eq(wbuf[9], 0, WCHAR, "%x");
expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
- expect_eq(StrCatBuffW(wbuf, wstr1, 100), wbuf, PWCHAR, "%p");
- expect_eq(wbuf[99], 0, WCHAR, "%x");
- expect_eq(wbuf[100], (WCHAR)0xbfbf, WCHAR, "%x");
- memset(wbuf, 0xbf, sizeof(wbuf));
- strret.uType = STRRET_WSTR;
- U(strret).pOleStr = StrDupW(wstr1);
- expect_eq(StrRetToBufW(&strret, NULL, wbuf, 10), S_OK, HRESULT, "%x");
- expect_eq(wbuf[9], 0, WCHAR, "%x");
- expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
+ if (pStrCatBuffW)
+ {
+ expect_eq(pStrCatBuffW(wbuf, wstr1, 100), wbuf, PWCHAR, "%p");
+ expect_eq(wbuf[99], 0, WCHAR, "%x");
+ expect_eq(wbuf[100], (WCHAR)0xbfbf, WCHAR, "%x");
+ }
+ else
+ skip("StrCatBuffW() is not available. Tests skipped\n");
- memset(buf, 0xbf, sizeof(buf));
- strret.uType = STRRET_CSTR;
- StrCpyN(U(strret).cStr, str1, MAX_PATH);
- expect_eq(StrRetToBufA(&strret, NULL, buf, 10), S_OK, HRESULT, "%x");
- expect_eq(buf[9], 0, CHAR, "%x");
- expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
+ if (pStrRetToBufW)
+ {
+ memset(wbuf, 0xbf, sizeof(wbuf));
+ strret.uType = STRRET_WSTR;
+ U(strret).pOleStr = StrDupW(wstr1);
+ expect_eq(pStrRetToBufW(&strret, NULL, wbuf, 10), S_OK, HRESULT, "%x");
+ expect_eq(wbuf[9], 0, WCHAR, "%x");
+ expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
+ }
+ else
+ skip("StrRetToBufW() is not available. Tests skipped\n");
- memset(buf, 0xbf, sizeof(buf));
- ret = wnsprintfA(buf, 10, "%s", str1);
- todo_wine ok(ret == 9, "Unexpected wsnprintfA return %d, expected 9\n", ret);
- expect_eq(buf[9], 0, CHAR, "%x");
- expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
- memset(wbuf, 0xbf, sizeof(wbuf));
- ret = wnsprintfW(wbuf, 10, fmt, wstr1);
- todo_wine ok(ret == 9, "Unexpected wsnprintfW return %d, expected 9\n", ret);
- expect_eq(wbuf[9], 0, WCHAR, "%x");
- expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
+ if (pStrRetToBufA)
+ {
+ memset(buf, 0xbf, sizeof(buf));
+ strret.uType = STRRET_CSTR;
+ StrCpyN(U(strret).cStr, str1, MAX_PATH);
+ expect_eq(pStrRetToBufA(&strret, NULL, buf, 10), S_OK, HRESULT, "%x");
+ expect_eq(buf[9], 0, CHAR, "%x");
+ expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
+ }
+ else
+ skip("StrRetToBufA() is not available. Tests skipped\n");
+
+ if (pwnsprintfA)
+ {
+ memset(buf, 0xbf, sizeof(buf));
+ ret = pwnsprintfA(buf, 10, "%s", str1);
+ todo_wine ok(ret == 9, "Unexpected wsnprintfA return %d, expected 9\n", ret);
+ expect_eq(buf[9], 0, CHAR, "%x");
+ expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
+ }
+ else
+ skip("wnsprintfA() is not available. Tests skipped\n");
+
+ if (pwnsprintfW)
+ {
+ memset(wbuf, 0xbf, sizeof(wbuf));
+ ret = pwnsprintfW(wbuf, 10, fmt, wstr1);
+ todo_wine ok(ret == 9, "Unexpected wsnprintfW return %d, expected 9\n", ret);
+ expect_eq(wbuf[9], 0, WCHAR, "%x");
+ expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
+ }
+ else
+ skip("wnsprintfW() is not available. Tests skipped\n");
}
START_TEST(string)
{
+ HMODULE hShlwapi;
TCHAR thousandDelim[8];
TCHAR decimalDelim[8];
CoInitialize(0);
@@ -830,6 +903,24 @@ START_TEST(string)
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimalDelim, 8);
hShlwapi = GetModuleHandleA("shlwapi");
+ pIntlStrEqWorkerA = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerA");
+ pIntlStrEqWorkerW = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerW");
+ pSHAnsiToAnsi = (void *)GetProcAddress(hShlwapi, (LPSTR)345);
+ pSHUnicodeToUnicode = (void *)GetProcAddress(hShlwapi, (LPSTR)346);
+ pStrCatBuffA = (void *)GetProcAddress(hShlwapi, "StrCatBuffA");
+ pStrCatBuffW = (void *)GetProcAddress(hShlwapi, "StrCatBuffW");
+ pStrCpyNXA = (void *)GetProcAddress(hShlwapi, (LPSTR)399);
+ pStrCpyNXW = (void *)GetProcAddress(hShlwapi, (LPSTR)400);
+ pStrFormatByteSize64A = (void *)GetProcAddress(hShlwapi, "StrFormatByteSize64A");
+ pStrFormatKBSizeA = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeA");
+ pStrFormatKBSizeW = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeW");
+ pStrIsIntlEqualA = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualA");
+ pStrIsIntlEqualW = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualW");
+ pStrRetToBSTR = (void *)GetProcAddress(hShlwapi, "StrRetToBSTR");
+ pStrRetToBufA = (void *)GetProcAddress(hShlwapi, "StrRetToBufA");
+ pStrRetToBufW = (void *)GetProcAddress(hShlwapi, "StrRetToBufW");
+ pwnsprintfA = (void *)GetProcAddress(hShlwapi, "wnsprintfA");
+ pwnsprintfW = (void *)GetProcAddress(hShlwapi, "wnsprintfW");
test_StrChrA();
test_StrChrW();
diff --git a/rostests/winetests/shlwapi/testlist.c b/rostests/winetests/shlwapi/testlist.c
index c34cd62b55a..dec5a258ff7 100755
--- a/rostests/winetests/shlwapi/testlist.c
+++ b/rostests/winetests/shlwapi/testlist.c
@@ -9,6 +9,7 @@
extern void func_clist(void);
extern void func_clsid(void);
extern void func_generated(void);
+extern void func_istream(void);
extern void func_ordinal(void);
extern void func_path(void);
extern void func_shreg(void);
@@ -20,6 +21,7 @@ const struct test winetest_testlist[] =
{ "clist", func_clist },
{ "clsid", func_clsid },
{ "generated", func_generated },
+ { "istream", func_istream },
{ "ordinal", func_ordinal },
{ "path", func_path },
{ "shreg", func_shreg },
diff --git a/rostests/winetests/shlwapi/url.c b/rostests/winetests/shlwapi/url.c
index 87b8b1de09e..2d63a216f61 100644
--- a/rostests/winetests/shlwapi/url.c
+++ b/rostests/winetests/shlwapi/url.c
@@ -206,6 +206,7 @@ static const TEST_URL_COMBINE TEST_COMBINE[] = {
{"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
{"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
{"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"},
+ {"C:\\winehq\\winehq.txt", "C:\\Test\\test.txt", 0, S_OK, "file:///C:/Test/test.txt"},
{"http://www.winehq.org/test/", "test%20file.txt", 0, S_OK, "http://www.winehq.org/test/test%20file.txt"},
{"http://www.winehq.org/test/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/test/test%20file.txt"},
{"http://www.winehq.org%2ftest/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org%2ftest/test%20file.txt"},
diff --git a/rostests/winetests/urlmon/generated.c b/rostests/winetests/urlmon/generated.c
index 99bec8140b5..d29c226ca17 100644
--- a/rostests/winetests/urlmon/generated.c
+++ b/rostests/winetests/urlmon/generated.c
@@ -19,7 +19,7 @@
#include "wine/test.h"
/***********************************************************************
- * Compability macros
+ * Compatibility macros
*/
#define DWORD_PTR UINT_PTR
diff --git a/rostests/winetests/urlmon/misc.c b/rostests/winetests/urlmon/misc.c
index ba36d8ac300..96612b076df 100644
--- a/rostests/winetests/urlmon/misc.c
+++ b/rostests/winetests/urlmon/misc.c
@@ -18,6 +18,7 @@
#define COBJMACROS
#define CONST_VTABLE
+#define NONAMELESSUNION
#include
#include
@@ -249,7 +250,7 @@ static void test_RegisterFormatEnumerator(void)
static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
'/','b','l','a','n','k','.','h','t','m',0};
static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
-static const WCHAR url3[] = {'f','i','l','e',':','c',':','\\','I','n','d','e','x','.','h','t','m',0};
+static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
'%','2','e','j','p','g',0};
static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
@@ -258,7 +259,11 @@ static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
'f','i','l','e','.','t','e','s','t',0};
static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
-
+static const WCHAR url9[] =
+ {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
+ '/','s','i','t','e','/','a','b','o','u','t',0};
+static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e',
+ '.','j','p','g',0};
static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
'.','j','p','g',0};
@@ -417,6 +422,7 @@ static const WCHAR mimeAppPdf[] = {'a','p','p','l','i','c','a','t','i','o','n','
static const WCHAR mimeAppXMSDownload[] =
{'a','p','p','l','i','c','a','t','i','o','n','/','x','-','m','s','d','o','w','n','l','o','a','d',0};
static const WCHAR mimeAudioWav[] = {'a','u','d','i','o','/','w','a','v',0};
+static const WCHAR mimeAudioBasic[] = {'a','u','d','i','o','/','b','a','s','i','c',0};
static const struct {
LPCWSTR url;
@@ -513,6 +519,10 @@ static BYTE data78[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'<','h','t','m','l',
static BYTE data79[] = {'%','!',0xff};
static BYTE data80[] = {'%','!'};
static BYTE data81[] = {'%','!','P','S','<','h','t','m','l','>'};
+static BYTE data82[] = {'.','s','n','d',0};
+static BYTE data83[] = {'.','s','n','d'};
+static BYTE data84[] = {'.','s','n','d',0,'<','h','t','m','l','>',1,1};
+static BYTE data85[] = {'.','S','N','D',0};
static const struct {
BYTE *data;
@@ -599,7 +609,11 @@ static const struct {
{data78, sizeof(data78), mimeTextHtml},
{data79, sizeof(data79), mimeAppPostscript},
{data80, sizeof(data80), mimeTextPlain},
- {data81, sizeof(data81), mimeTextHtml}
+ {data81, sizeof(data81), mimeTextHtml},
+ {data82, sizeof(data82), mimeAudioBasic},
+ {data83, sizeof(data83), mimeTextPlain},
+ {data84, sizeof(data84), mimeTextHtml},
+ {data85, sizeof(data85), mimeTextPlain}
};
static void test_FindMimeFromData(void)
@@ -700,12 +714,13 @@ static void test_FindMimeFromData(void)
}
static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0};
-static const BYTE secid4[] ={'f','i','l','e',':',3,0,0,0};
static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','w','i','n','e','h','q',
'.','o','r','g',3,0,0,0};
static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0};
static const BYTE secid7[] = {'f','t','p',':','w','i','n','e','h','q','.','o','r','g',
3,0,0,0};
+static const BYTE secid10[] =
+ {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e','.','j','p','g',3,0,0,0};
static struct secmgr_test {
LPCWSTR url;
@@ -718,7 +733,7 @@ static struct secmgr_test {
{url1, 0, S_OK, sizeof(secid1), secid1, S_OK},
{url2, 100, 0x80041001, 0, NULL, E_INVALIDARG},
{url3, 0, S_OK, sizeof(secid1), secid1, S_OK},
- {url4, 3, S_OK, sizeof(secid4), secid4, S_OK},
+ {url10,3, S_OK, sizeof(secid10),secid10,S_OK},
{url5, 3, S_OK, sizeof(secid5), secid5, S_OK},
{url6, 3, S_OK, sizeof(secid6), secid6, S_OK},
{url7, 3, S_OK, sizeof(secid7), secid7, S_OK}
@@ -729,7 +744,7 @@ static void test_SecurityManager(void)
int i;
IInternetSecurityManager *secmgr = NULL;
BYTE buf[512];
- DWORD zone, size;
+ DWORD zone, size, policy;
HRESULT hres;
hres = CoInternetCreateSecurityManager(NULL, &secmgr, 0);
@@ -741,7 +756,8 @@ static void test_SecurityManager(void)
zone = 100;
hres = IInternetSecurityManager_MapUrlToZone(secmgr, secmgr_tests[i].url,
&zone, 0);
- ok(hres == secmgr_tests[i].zone_hres,
+ ok(hres == secmgr_tests[i].zone_hres /* IE <=6 */
+ || (FAILED(secmgr_tests[i].zone_hres) && hres == E_INVALIDARG), /* IE7 */
"[%d] MapUrlToZone failed: %08x, expected %08x\n",
i, hres, secmgr_tests[i].zone_hres);
if(SUCCEEDED(hres))
@@ -782,9 +798,103 @@ static void test_SecurityManager(void)
ok(hres == E_INVALIDARG,
"GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
+ hres = IInternetSecurityManager_ProcessUrlAction(secmgr, NULL, URLACTION_SCRIPT_RUN, (BYTE*)&policy,
+ sizeof(WCHAR), NULL, 0, 0, 0);
+ ok(hres == E_INVALIDARG, "ProcessUrlAction failed: %08x, expected E_INVALIDARG\n", hres);
+
IInternetSecurityManager_Release(secmgr);
}
+static void test_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
+{
+ DWORD res, size, policy, reg_policy;
+ char buf[10];
+ HKEY hkey;
+ HRESULT hres;
+
+ res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3", &hkey);
+ if(res != ERROR_SUCCESS) {
+ ok(0, "Could not open zone key\n");
+ return;
+ }
+
+ wsprintf(buf, "%X", action);
+ size = sizeof(DWORD);
+ res = RegQueryValueExA(hkey, buf, NULL, NULL, (BYTE*)®_policy, &size);
+ RegCloseKey(hkey);
+ if(res != ERROR_SUCCESS || size != sizeof(DWORD)) {
+ policy = 0xdeadbeef;
+ hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
+ sizeof(WCHAR), NULL, 0, 0, 0);
+ ok(hres == E_FAIL, "ProcessUrlAction(%x) failed: %08x, expected E_FAIL\n", action, hres);
+ ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
+
+ policy = 0xdeadbeef;
+ hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
+ sizeof(DWORD), URLZONEREG_DEFAULT);
+ ok(hres == E_FAIL, "GetZoneActionPolicy failed: %08x, expected E_FAIL\n", hres);
+ ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
+ return;
+ }
+
+ policy = 0xdeadbeef;
+ hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
+ sizeof(DWORD), URLZONEREG_DEFAULT);
+ ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
+ ok(policy == reg_policy, "(%x) policy=%x, expected %x\n", action, policy, reg_policy);
+
+ if(policy != URLPOLICY_QUERY) {
+ policy = 0xdeadbeef;
+ hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url9, action, (BYTE*)&policy,
+ sizeof(WCHAR), NULL, 0, 0, 0);
+ if(reg_policy == URLPOLICY_DISALLOW)
+ ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
+ else
+ ok(hres == S_OK, "ProcessUrlAction(%x) failed: %08x\n", action, hres);
+ ok(policy == 0xdeadbeef, "(%x) policy=%x\n", action, policy);
+ }
+}
+
+static void test_special_url_action(IInternetSecurityManager *secmgr, IInternetZoneManager *zonemgr, DWORD action)
+{
+ DWORD policy;
+ HRESULT hres;
+
+ policy = 0xdeadbeef;
+ hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, (BYTE*)&policy,
+ sizeof(DWORD), URLZONEREG_DEFAULT);
+ ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
+ ok(policy == URLPOLICY_DISALLOW, "(%x) policy=%x, expected URLPOLIVY_DISALLOW\n", action, policy);
+
+ policy = 0xdeadbeef;
+ hres = IInternetSecurityManager_ProcessUrlAction(secmgr, url1, action, (BYTE*)&policy,
+ sizeof(WCHAR), NULL, 0, 0, 0);
+ ok(hres == S_FALSE, "ProcessUrlAction(%x) failed: %08x, expected S_FALSE\n", action, hres);
+}
+
+static void test_polices(void)
+{
+ IInternetZoneManager *zonemgr = NULL;
+ IInternetSecurityManager *secmgr = NULL;
+ HRESULT hres;
+
+ hres = CoInternetCreateSecurityManager(NULL, &secmgr, 0);
+ ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
+ hres = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
+ ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
+
+ test_url_action(secmgr, zonemgr, URLACTION_SCRIPT_RUN);
+ test_url_action(secmgr, zonemgr, URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY);
+ test_url_action(secmgr, zonemgr, URLACTION_CHANNEL_SOFTDIST_PERMISSIONS);
+ test_url_action(secmgr, zonemgr, 0xdeadbeef);
+
+ test_special_url_action(secmgr, zonemgr, URLACTION_SCRIPT_OVERRIDE_SAFETY);
+
+ IInternetSecurityManager_Release(secmgr);
+ IInternetZoneManager_Release(zonemgr);
+}
+
static void test_ZoneManager(void)
{
IInternetZoneManager *zonemgr = NULL;
@@ -1174,6 +1284,50 @@ static void test_ReleaseBindInfo(void)
ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
}
+static void test_CopyStgMedium(void)
+{
+ STGMEDIUM src, dst;
+ HRESULT hres;
+
+ static WCHAR fileW[] = {'f','i','l','e',0};
+
+ memset(&src, 0xf0, sizeof(src));
+ memset(&dst, 0xe0, sizeof(dst));
+ src.tymed = TYMED_NULL;
+ src.pUnkForRelease = NULL;
+ hres = CopyStgMedium(&src, &dst);
+ ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
+ ok(dst.tymed == TYMED_NULL, "tymed=%d\n", dst.tymed);
+ ok(dst.u.hGlobal == (void*)0xf0f0f0f0, "u=%p\n", dst.u.hGlobal);
+ ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
+
+ memset(&dst, 0xe0, sizeof(dst));
+ src.tymed = TYMED_ISTREAM;
+ src.u.pstm = NULL;
+ src.pUnkForRelease = NULL;
+ hres = CopyStgMedium(&src, &dst);
+ ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
+ ok(dst.tymed == TYMED_ISTREAM, "tymed=%d\n", dst.tymed);
+ ok(!dst.u.pstm, "pstm=%p\n", dst.u.pstm);
+ ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
+
+ memset(&dst, 0xe0, sizeof(dst));
+ src.tymed = TYMED_FILE;
+ src.u.lpszFileName = fileW;
+ src.pUnkForRelease = NULL;
+ hres = CopyStgMedium(&src, &dst);
+ ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
+ ok(dst.tymed == TYMED_FILE, "tymed=%d\n", dst.tymed);
+ ok(dst.u.lpszFileName && dst.u.lpszFileName != fileW, "lpszFileName=%p\n", dst.u.lpszFileName);
+ ok(!lstrcmpW(dst.u.lpszFileName, fileW), "wrong file name\n");
+ ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
+
+ hres = CopyStgMedium(&src, NULL);
+ ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
+ hres = CopyStgMedium(NULL, &dst);
+ ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
+}
+
static void test_UrlMkGetSessionOption(void)
{
DWORD encoding, size;
@@ -1271,6 +1425,54 @@ static void test_ObtainUserAgentString(void)
HeapFree(GetProcessHeap(), 0, str2);
}
+static void test_MkParseDisplayNameEx(void)
+{
+ IMoniker *mon = NULL;
+ LPWSTR name;
+ DWORD issys;
+ ULONG eaten = 0;
+ IBindCtx *bctx;
+ HRESULT hres;
+
+ static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
+ '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
+ '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
+
+ CreateBindCtx(0, &bctx);
+
+ hres = MkParseDisplayNameEx(bctx, url9, &eaten, &mon);
+ ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
+ ok(eaten == sizeof(url9)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+ ok(mon != NULL, "mon == NULL\n");
+
+ hres = IMoniker_GetDisplayName(mon, NULL, 0, &name);
+ ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
+ ok(!lstrcmpW(name, url9), "wrong display name %s\n", debugstr_w(name));
+ CoTaskMemFree(name);
+
+ hres = IMoniker_IsSystemMoniker(mon, &issys);
+ ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
+ ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
+
+ IMoniker_Release(mon);
+
+ hres = MkParseDisplayNameEx(bctx, clsid_nameW, &eaten, &mon);
+ ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
+ ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+ ok(mon != NULL, "mon == NULL\n");
+
+ hres = IMoniker_IsSystemMoniker(mon, &issys);
+ ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
+ ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
+
+ IMoniker_Release(mon);
+
+ hres = MkParseDisplayNameEx(bctx, url8, &eaten, &mon);
+ ok(FAILED(hres), "MkParseDisplayNameEx succeeded: %08x\n", hres);
+
+ IBindCtx_Release(bctx);
+}
+
START_TEST(misc)
{
OleInitialize(NULL);
@@ -1284,12 +1486,15 @@ START_TEST(misc)
test_CoInternetQueryInfo();
test_FindMimeFromData();
test_SecurityManager();
+ test_polices();
test_ZoneManager();
test_NameSpace();
test_MimeFilter();
test_ReleaseBindInfo();
+ test_CopyStgMedium();
test_UrlMkGetSessionOption();
test_ObtainUserAgentString();
+ test_MkParseDisplayNameEx();
OleUninitialize();
}
diff --git a/rostests/winetests/urlmon/protocol.c b/rostests/winetests/urlmon/protocol.c
index fd92171e10d..c21134b0280 100644
--- a/rostests/winetests/urlmon/protocol.c
+++ b/rostests/winetests/urlmon/protocol.c
@@ -36,19 +36,18 @@
#define SET_EXPECT(func) \
expect_ ## func = TRUE
-#define CHECK_EXPECT(func) \
- do { \
- ok(expect_ ##func, "unexpected call " #func "\n"); \
- expect_ ## func = FALSE; \
- called_ ## func = TRUE; \
- }while(0)
-
#define CHECK_EXPECT2(func) \
do { \
ok(expect_ ##func, "unexpected call " #func "\n"); \
called_ ## func = TRUE; \
}while(0)
+#define CHECK_EXPECT(func) \
+ do { \
+ CHECK_EXPECT2(func); \
+ expect_ ## func = FALSE; \
+ }while(0)
+
#define CHECK_CALLED(func) \
do { \
ok(called_ ## func, "expected " #func "\n"); \
@@ -357,6 +356,8 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL
CHECK_CALLED(ReportProgress_SENDINGREQUEST);
SET_EXPECT(OnResponse);
SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
+ if(bindf & BINDF_NEEDFILE)
+ SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
}
SET_EXPECT(ReportData);
@@ -368,6 +369,8 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL
state = 1;
CHECK_CALLED(OnResponse);
CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
+ if(bindf & BINDF_NEEDFILE)
+ CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
}
SetEvent(event_complete);
@@ -423,8 +426,10 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface,
if(szStatusText) {
if(binding_test)
ok(szStatusText == expect_wsz, "unexpected szStatusText\n");
+ else if(tested_protocol == FILE_TEST)
+ ok(!lstrcmpW(szStatusText, file_name), "szStatusText = \"%s\"\n", debugstr_w(szStatusText));
else
- ok(!lstrcmpW(szStatusText, file_name), "szStatusText != file_name\n");
+ ok(szStatusText != NULL, "szStatusText == NULL\n");
}
break;
case BINDSTATUS_FINDINGRESOURCE:
@@ -1408,6 +1413,8 @@ static void test_file_protocol(void) {
test_file_protocol_url(index_url);
bindf = BINDF_FROMURLMON;
test_file_protocol_url(index_url);
+ bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
+ test_file_protocol_url(index_url);
memcpy(buf, wszFile, sizeof(wszFile));
len = sizeof(wszFile)/sizeof(WCHAR)-1;
@@ -1639,11 +1646,15 @@ static void test_http_protocol(void)
bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
test_http_protocol_url(winehq_url, FALSE);
+ trace("Testing http protocol (to file)...\n");
+ bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
+ test_http_protocol_url(winehq_url, FALSE);
+
trace("Testing http protocol (post data)...\n");
http_post_test = TRUE;
/* Without this flag we get a ReportProgress_CACHEFILENAMEAVAILABLE
* notification with BINDVERB_POST */
- bindf |= BINDF_NOWRITECACHE;
+ bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
test_http_protocol_url(posttest_url, TRUE);
http_post_test = FALSE;
}
@@ -1700,7 +1711,7 @@ static void test_mk_protocol(void)
ok(hres == INET_E_RESOURCE_NOT_FOUND, "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
CHECK_CALLED(GetBindInfo);
- CHECK_CALLED(ReportProgress_DIRECTBIND);
+ CLEAR_CALLED(ReportProgress_DIRECTBIND);
CHECK_CALLED(ReportProgress_SENDINGREQUEST);
CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
CHECK_CALLED(ReportResult);
diff --git a/rostests/winetests/urlmon/stream.c b/rostests/winetests/urlmon/stream.c
index 12133f9e730..72a1d43c61c 100644
--- a/rostests/winetests/urlmon/stream.c
+++ b/rostests/winetests/urlmon/stream.c
@@ -167,7 +167,7 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP
ok(szStatusText != NULL, "szStatusText == NULL\n");
break;
default:
- todo_wine { ok(0, "unexpexted code %d\n", ulStatusCode); }
+ todo_wine { ok(0, "unexpected code %d\n", ulStatusCode); }
};
return S_OK;
}
diff --git a/rostests/winetests/urlmon/url.c b/rostests/winetests/urlmon/url.c
index 8ac533a6768..5c8505c88e5 100644
--- a/rostests/winetests/urlmon/url.c
+++ b/rostests/winetests/urlmon/url.c
@@ -23,6 +23,7 @@
#include
#define COBJMACROS
+#define NONAMELESSUNION
#define CONST_VTABLE
#include "windef.h"
@@ -37,7 +38,7 @@
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
#define SET_EXPECT(func) \
- expect_ ## func = TRUE
+ do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
#define CHECK_EXPECT2(func) \
do { \
@@ -89,6 +90,7 @@ DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE);
DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA);
DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA);
DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA);
+DEFINE_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
DEFINE_EXPECT(OnStopBinding);
DEFINE_EXPECT(OnDataAvailable);
DEFINE_EXPECT(OnObjectAvailable);
@@ -104,6 +106,7 @@ DEFINE_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
DEFINE_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
DEFINE_EXPECT(Obj_OnProgress_FINDINGRESOURCE);
DEFINE_EXPECT(Obj_OnProgress_CONNECTING);
+DEFINE_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
DEFINE_EXPECT(Start);
DEFINE_EXPECT(Read);
DEFINE_EXPECT(LockRequest);
@@ -140,11 +143,13 @@ static const WCHAR wszWineHQSite[] =
static const WCHAR wszWineHQIP[] =
{'2','0','9','.','3','2','.','1','4','1','.','3',0};
static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
+static const WCHAR cache_fileW[] = {'c',':','\\','c','a','c','h','e','.','h','t','m',0};
+static const WCHAR dwl_htmlW[] = {'d','w','l','.','h','t','m','l',0};
static const WCHAR emptyW[] = {0};
static BOOL stopped_binding = FALSE, stopped_obj_binding = FALSE, emulate_protocol = FALSE,
- data_available = FALSE, http_is_first = TRUE, bind_to_object = FALSE;
-static DWORD read = 0, bindf = 0, prot_state = 0, thread_id;
+ data_available = FALSE, http_is_first = TRUE, bind_to_object = FALSE, filedwl_api;
+static DWORD read = 0, bindf = 0, prot_state = 0, thread_id, tymed;
static CHAR mime_type[512];
static IInternetProtocolSink *protocol_sink = NULL;
static HANDLE complete_event, complete_event2;
@@ -160,6 +165,8 @@ static LPCWSTR urls[] = {
MK_URL
};
+static WCHAR file_url[INTERNET_MAX_URL_LENGTH];
+
static enum {
HTTP_TEST,
ABOUT_TEST,
@@ -337,8 +344,9 @@ static DWORD WINAPI thread_proc(PVOID arg)
CHECK_CALLED(OnDataAvailable);
CHECK_CALLED(OnStopBinding);
- SetEvent(complete_event2);
+ SET_EXPECT(Read);
+ SetEvent(complete_event2);
return 0;
}
@@ -357,13 +365,14 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
read = 0;
- ok(szUrl && !lstrcmpW(szUrl, urls[test_protocol]), "wrong url\n");
+ if(!filedwl_api) /* FIXME */
+ ok(szUrl && !lstrcmpW(szUrl, urls[test_protocol]), "wrong url %s\n", debugstr_w(szUrl));
ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
ok(grfPI == 0, "grfPI=%d, expected 0\n", grfPI);
ok(dwReserved == 0, "dwReserved=%d, expected 0\n", dwReserved);
- if(binding_hres != S_OK) {
+ if(!filedwl_api && binding_hres != S_OK) {
SET_EXPECT(OnStopBinding);
SET_EXPECT(Terminate);
hres = IInternetProtocolSink_ReportResult(pOIProtSink, binding_hres, 0, NULL);
@@ -379,13 +388,16 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
- if(test_protocol == FILE_TEST || test_protocol == MK_TEST || test_protocol == HTTP_TEST) {
+ if(filedwl_api) {
+ ok(bindf == (BINDF_PULLDATA|BINDF_FROMURLMON|BINDF_NEEDFILE), "bindf=%08x\n", bindf);
+ }else if(tymed == TYMED_ISTREAM
+ && (test_protocol == FILE_TEST || test_protocol == MK_TEST || test_protocol == HTTP_TEST)) {
ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA
|BINDF_FROMURLMON),
"bindf=%08x\n", bindf);
}else {
- ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA|
- BINDF_FROMURLMON|BINDF_NEEDFILE),
+ ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA
+ |BINDF_FROMURLMON|BINDF_NEEDFILE),
"bindf=%08x\n", bindf);
}
@@ -513,7 +525,7 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
if(test_protocol == FILE_TEST) {
hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
- BINDSTATUS_CACHEFILENAMEAVAILABLE, emptyW);
+ BINDSTATUS_CACHEFILENAMEAVAILABLE, file_url+8);
ok(hres == S_OK,
"ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
@@ -546,6 +558,8 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
SET_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ SET_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
SET_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
SET_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
SET_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
@@ -560,9 +574,12 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
SET_EXPECT(LockRequest);
- SET_EXPECT(OnDataAvailable);
+ if(!filedwl_api)
+ SET_EXPECT(OnDataAvailable);
SET_EXPECT(OnStopBinding);
}
@@ -574,6 +591,8 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ CHECK_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
CHECK_CALLED(Obj_OnProgress_ENDDOWNLOADDATA);
CHECK_CALLED(Obj_OnProgress_CLASSIDAVAILABLE);
CHECK_CALLED(Obj_OnProgress_BEGINSYNCOPERATION);
@@ -588,9 +607,12 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
CHECK_CALLED(LockRequest);
- CHECK_CALLED(OnDataAvailable);
+ if(!filedwl_api)
+ CHECK_CALLED(OnDataAvailable);
CHECK_CALLED(OnStopBinding);
}
@@ -648,6 +670,13 @@ static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
ok(hres == S_OK,
"ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
+ if(tymed == TYMED_FILE) {
+ hres = IInternetProtocolSink_ReportProgress(protocol_sink,
+ BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_fileW);
+ ok(hres == S_OK,
+ "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
+ }
+
bscf |= BSCF_FIRSTDATANOTIFICATION;
break;
}
@@ -1133,8 +1162,13 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP
else
CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
ok(szStatusText != NULL, "szStatusText == NULL\n");
- if(szStatusText)
- ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
+ if(szStatusText) {
+ if(filedwl_api) {
+ /* FIXME */
+ }else {
+ ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText %s\n", debugstr_w(szStatusText));
+ }
+ }
if(!bind_to_object)
ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
download_state);
@@ -1153,16 +1187,31 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP
else
CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
ok(szStatusText != NULL, "szStatusText == NULL\n");
- if(szStatusText)
- ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
+ if(szStatusText) {
+ if(filedwl_api) {
+ /* FIXME */
+ }else {
+ ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText %s\n", debugstr_w(szStatusText));
+ }
+ }
ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
download_state);
download_state = END_DOWNLOAD;
break;
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
+ if(test_protocol != HTTP_TEST) {
+ if(iface == &objbsc)
+ CHECK_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
+ else
+ CHECK_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
+ }else { /* FIXME */
+ CLEAR_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
+ CLEAR_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
+ }
+
ok(szStatusText != NULL, "szStatusText == NULL\n");
if(szStatusText && test_protocol == FILE_TEST)
- ok(!lstrcmpW(INDEX_HTML+7, szStatusText), "wrong szStatusText\n");
+ ok(!lstrcmpW(file_url+8, szStatusText), "wrong szStatusText %s\n", debugstr_w(szStatusText));
break;
case BINDSTATUS_CLASSIDAVAILABLE:
{
@@ -1193,7 +1242,7 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP
ok(szStatusText == NULL, "Expected szStatusText to be NULL\n");
break;
default:
- ok(0, "unexpexted code %d\n", ulStatusCode);
+ ok(0, "unexpected code %d\n", ulStatusCode);
};
return S_OK;
}
@@ -1214,7 +1263,10 @@ static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallback *iface, HRESUL
if (hresult == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
return S_OK;
- ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres);
+ if(filedwl_api)
+ ok(SUCCEEDED(hresult), "binding failed: %08x\n", hresult);
+ else
+ ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres);
ok(szError == NULL, "szError should be NULL\n");
if(test_protocol == HTTP_TEST && emulate_protocol) {
@@ -1279,34 +1331,42 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWOR
ok(pformatetc->ptd == NULL, "ptd = %p\n", pformatetc->ptd);
ok(pformatetc->dwAspect == 1, "dwAspect=%u\n", pformatetc->dwAspect);
ok(pformatetc->lindex == -1, "lindex=%d\n", pformatetc->lindex);
- ok(pformatetc->tymed == TYMED_ISTREAM, "tymed=%u\n", pformatetc->tymed);
+ ok(pformatetc->tymed == tymed, "tymed=%u, expected %u\n", pformatetc->tymed, tymed);
}
ok(pstgmed != NULL, "stgmeg == NULL\n");
- if(pstgmed) {
- ok(pstgmed->tymed == TYMED_ISTREAM, "tymed=%u\n", pstgmed->tymed);
- ok(U(*pstgmed).pstm != NULL, "pstm == NULL\n");
- ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
- }
+ ok(pstgmed->tymed == tymed, "tymed=%u, expected %u\n", pstgmed->tymed, tymed);
+ ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
- if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
- hres = IStream_Write(U(*pstgmed).pstm, buf, 10, NULL);
- ok(hres == STG_E_ACCESSDENIED,
- "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
+ switch(pstgmed->tymed) {
+ case TYMED_ISTREAM:
+ if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
+ hres = IStream_Write(U(*pstgmed).pstm, buf, 10, NULL);
+ ok(hres == STG_E_ACCESSDENIED,
+ "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
- hres = IStream_Commit(U(*pstgmed).pstm, 0);
- ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
+ hres = IStream_Commit(U(*pstgmed).pstm, 0);
+ ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
- hres = IStream_Revert(U(*pstgmed).pstm);
- ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
- }
+ hres = IStream_Revert(U(*pstgmed).pstm);
+ ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
+ }
- ok(U(*pstgmed).pstm != NULL, "U(*pstgmed).pstm == NULL\n");
-
- if(U(*pstgmed).pstm) {
+ ok(U(*pstgmed).pstm != NULL, "U(*pstgmed).pstm == NULL\n");
do hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed);
while(hres == S_OK);
ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
+ break;
+
+ case TYMED_FILE:
+ if(test_protocol == FILE_TEST)
+ ok(!lstrcmpW(pstgmed->u.lpszFileName, INDEX_HTML+7),
+ "unexpected file name %s\n", debugstr_w(pstgmed->u.lpszFileName));
+ else if(emulate_protocol)
+ ok(!lstrcmpW(pstgmed->u.lpszFileName, cache_fileW),
+ "unexpected file name %s\n", debugstr_w(pstgmed->u.lpszFileName));
+ else
+ ok(pstgmed->u.lpszFileName != NULL, "lpszFileName == NULL\n");
}
if(test_protocol == HTTP_TEST && emulate_protocol && prot_state < 4 && (!bind_to_object || prot_state > 1))
@@ -1325,9 +1385,6 @@ static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallback *iface, RE
ok(IsEqualGUID(&IID_IUnknown, riid), "riid = %s\n", debugstr_guid(riid));
ok(punk != NULL, "punk == NULL\n");
- if(0&&test_protocol == HTTP_TEST)
- SetEvent(complete_event);
-
return S_OK;
}
@@ -1441,8 +1498,6 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva
CHECK_EXPECT(Load);
ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
- trace("LOAD %p\n", pibc);
-
if(test_protocol == HTTP_TEST)
ok(!fFullyAvailable, "fFulyAvailable = %x\n", fFullyAvailable);
else
@@ -1470,9 +1525,9 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva
SET_EXPECT(GetBindInfo);
SET_EXPECT(OnStartBinding);
- if(test_protocol == FILE_TEST)
- SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
if(test_protocol != HTTP_TEST)
SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
SET_EXPECT(LockRequest);
@@ -1485,9 +1540,9 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva
CHECK_CALLED(GetBindInfo);
CHECK_CALLED(OnStartBinding);
- if(test_protocol == FILE_TEST)
- todo_wine CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
if(test_protocol != HTTP_TEST)
CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
CHECK_CALLED(LockRequest);
@@ -1764,26 +1819,27 @@ static void test_bscholder(IBindStatusCallback *holder)
IHttpNegotiate_Release(http_negotiate_serv);
hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate2, (void**)&http_negotiate2);
- ok(hres == S_OK, "Could not get IHttpNegotiate2 interface: %08x\n", hres);
+ if(SUCCEEDED(hres)) {
+ hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
+ ok(hres == E_FAIL, "GetRootSecurityId failed: %08x\n", hres);
- hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
- ok(hres == E_FAIL, "GetRootSecurityId failed: %08x\n", hres);
+ SET_EXPECT(QueryInterface_IHttpNegotiate2);
+ hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate2, &IID_IHttpNegotiate2,
+ (void**)&http_negotiate2_serv);
+ ok(hres == S_OK, "Could not get IHttpNegotiate2 service: %08x\n", hres);
+ CHECK_CALLED(QueryInterface_IHttpNegotiate2);
+ ok(http_negotiate2 == http_negotiate2_serv, "http_negotiate != http_negotiate_serv\n");
- IHttpNegotiate_Release(http_negotiate2);
+ SET_EXPECT(GetRootSecurityId);
+ hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
+ ok(hres == E_NOTIMPL, "GetRootSecurityId failed: %08x\n", hres);
+ CHECK_CALLED(GetRootSecurityId);
- SET_EXPECT(QueryInterface_IHttpNegotiate2);
- hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate2, &IID_IHttpNegotiate2,
- (void**)&http_negotiate2_serv);
- ok(hres == S_OK, "Could not get IHttpNegotiate2 service: %08x\n", hres);
- CHECK_CALLED(QueryInterface_IHttpNegotiate2);
- ok(http_negotiate2 == http_negotiate2_serv, "http_negotiate != http_negotiate_serv\n");
-
- SET_EXPECT(GetRootSecurityId);
- hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
- ok(hres == E_NOTIMPL, "GetRootSecurityId failed: %08x\n", hres);
- CHECK_CALLED(GetRootSecurityId);
-
- IHttpNegotiate_Release(http_negotiate2_serv);
+ IHttpNegotiate_Release(http_negotiate2_serv);
+ IHttpNegotiate_Release(http_negotiate2);
+ }else {
+ skip("Could not get IHttpNegotiate2\n");
+ }
SET_EXPECT(OnProgress_FINDINGRESOURCE);
hres = IBindStatusCallback_OnProgress(holder, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
@@ -1896,20 +1952,26 @@ static void test_RegisterBindStatusCallback(void)
IBindCtx_Release(bindctx);
}
-static void init_bind_test(int protocol, BOOL emul, BOOL bto)
+#define BINDTEST_EMULATE 1
+#define BINDTEST_TOOBJECT 2
+#define BINDTEST_FILEDWLAPI 4
+
+static void init_bind_test(int protocol, DWORD flags, DWORD t)
{
test_protocol = protocol;
- emulate_protocol = emul;
+ emulate_protocol = (flags & BINDTEST_EMULATE) != 0;
download_state = BEFORE_DOWNLOAD;
stopped_binding = FALSE;
stopped_obj_binding = FALSE;
data_available = FALSE;
mime_type[0] = 0;
binding_hres = S_OK;
- bind_to_object = bto;
+ bind_to_object = (flags & BINDTEST_TOOBJECT) != 0;
+ tymed = t;
+ filedwl_api = (flags & BINDTEST_FILEDWLAPI) != 0;
}
-static void test_BindToStorage(int protocol, BOOL emul)
+static void test_BindToStorage(int protocol, BOOL emul, DWORD t)
{
IMoniker *mon;
HRESULT hres;
@@ -1920,7 +1982,7 @@ static void test_BindToStorage(int protocol, BOOL emul)
IUnknown *unk = (IUnknown*)0x00ff00ff;
IBinding *bind;
- init_bind_test(protocol, emul, FALSE);
+ init_bind_test(protocol, emul ? BINDTEST_EMULATE : 0, t);
SET_EXPECT(QueryInterface_IServiceProvider);
hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx);
@@ -1937,16 +1999,13 @@ static void test_BindToStorage(int protocol, BOOL emul)
if(previousclb)
IBindStatusCallback_Release(previousclb);
- hres = CreateURLMoniker(NULL, urls[test_protocol], &mon);
+ hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon);
ok(SUCCEEDED(hres), "failed to create moniker: %08x\n", hres);
if(FAILED(hres)) {
IBindCtx_Release(bctx);
return;
}
- if(test_protocol == FILE_TEST && INDEX_HTML[7] == '/')
- memmove(INDEX_HTML+7, INDEX_HTML+8, lstrlenW(INDEX_HTML+7)*sizeof(WCHAR));
-
hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
if(SUCCEEDED(hres))
@@ -1958,6 +2017,9 @@ static void test_BindToStorage(int protocol, BOOL emul)
"GetDisplayName got wrong name %s\n", debugstr_w(display_name));
CoTaskMemFree(display_name);
+ if(tymed == TYMED_FILE && (test_protocol == ABOUT_TEST || test_protocol == ITS_TEST))
+ binding_hres = INET_E_DATA_NOT_AVAILABLE;
+
SET_EXPECT(GetBindInfo);
SET_EXPECT(QueryInterface_IInternetProtocol);
if(!emulate_protocol)
@@ -1967,9 +2029,12 @@ static void test_BindToStorage(int protocol, BOOL emul)
SET_EXPECT(Start);
if(test_protocol == HTTP_TEST)
SET_EXPECT(Terminate);
- SET_EXPECT(UnlockRequest);
+ if(tymed != TYMED_FILE || (test_protocol != ABOUT_TEST && test_protocol != ITS_TEST))
+ SET_EXPECT(UnlockRequest);
}else {
if(test_protocol == HTTP_TEST) {
+ SET_EXPECT(QueryInterface_IInternetBindInfo);
+ SET_EXPECT(QueryService_IInternetBindInfo);
SET_EXPECT(QueryInterface_IHttpNegotiate);
SET_EXPECT(BeginningTransaction);
SET_EXPECT(QueryInterface_IHttpNegotiate2);
@@ -1983,24 +2048,31 @@ static void test_BindToStorage(int protocol, BOOL emul)
SET_EXPECT(OnResponse);
SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
if(test_protocol == HTTP_TEST)
SET_EXPECT(OnProgress_DOWNLOADINGDATA);
SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
- SET_EXPECT(OnDataAvailable);
+ if(tymed != TYMED_FILE || test_protocol != ABOUT_TEST)
+ SET_EXPECT(OnDataAvailable);
SET_EXPECT(OnStopBinding);
}
- hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
+ hres = IMoniker_BindToStorage(mon, bctx, NULL, tymed == TYMED_ISTREAM ? &IID_IStream : &IID_IUnknown, (void**)&unk);
if (test_protocol == HTTP_TEST && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
{
- trace( "Network unreachable, skipping tests\n" );
+ skip("Network unreachable, skipping tests\n");
return;
}
- if (!SUCCEEDED(hres)) return;
- if((bindf & BINDF_ASYNCHRONOUS) && !data_available) {
+ if(((bindf & BINDF_ASYNCHRONOUS) && !data_available)
+ || (tymed == TYMED_FILE && test_protocol == FILE_TEST)) {
ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres);
ok(unk == NULL, "istr should be NULL\n");
+ }else if(tymed == TYMED_FILE && test_protocol == ABOUT_TEST) {
+ ok(hres == INET_E_DATA_NOT_AVAILABLE,
+ "IMoniker_BindToStorage failed: %08x, expected INET_E_DATA_NOT_AVAILABLE\n", hres);
+ ok(unk == NULL, "istr should be NULL\n");
}else {
ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
ok(unk != NULL, "unk == NULL\n");
@@ -2008,6 +2080,9 @@ static void test_BindToStorage(int protocol, BOOL emul)
if(unk)
IUnknown_Release(unk);
+ if(FAILED(hres))
+ return;
+
while((bindf & BINDF_ASYNCHRONOUS) &&
!stopped_binding && GetMessage(&msg,NULL,0,0)) {
TranslateMessage(&msg);
@@ -2021,11 +2096,17 @@ static void test_BindToStorage(int protocol, BOOL emul)
CHECK_CALLED(OnStartBinding);
if(emulate_protocol) {
CHECK_CALLED(Start);
- if(test_protocol == HTTP_TEST)
+ if(test_protocol == HTTP_TEST) {
+ if(tymed == TYMED_FILE)
+ CLEAR_CALLED(Read);
CHECK_CALLED(Terminate);
- CHECK_CALLED(UnlockRequest);
+ }
+ if(tymed != TYMED_FILE || (test_protocol != ABOUT_TEST && test_protocol != ITS_TEST))
+ CHECK_CALLED(UnlockRequest);
}else {
if(test_protocol == HTTP_TEST) {
+ CLEAR_CALLED(QueryInterface_IInternetBindInfo);
+ CLEAR_CALLED(QueryService_IInternetBindInfo);
CHECK_CALLED(QueryInterface_IHttpNegotiate);
CHECK_CALLED(BeginningTransaction);
/* QueryInterface_IHttpNegotiate2 and GetRootSecurityId
@@ -2046,10 +2127,13 @@ static void test_BindToStorage(int protocol, BOOL emul)
CHECK_CALLED(OnResponse);
CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
if(test_protocol == HTTP_TEST)
CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
- CHECK_CALLED(OnDataAvailable);
+ if(tymed != TYMED_FILE || test_protocol != ABOUT_TEST)
+ CHECK_CALLED(OnDataAvailable);
CHECK_CALLED(OnStopBinding);
}
@@ -2071,7 +2155,7 @@ static void test_BindToObject(int protocol, BOOL emul)
IUnknown *unk = (IUnknown*)0x00ff00ff;
IBinding *bind;
- init_bind_test(protocol, emul, TRUE);
+ init_bind_test(protocol, BINDTEST_TOOBJECT | (emul ? BINDTEST_EMULATE : 0), TYMED_ISTREAM);
if(emul)
CoRegisterClassObject(&CLSID_HTMLDocument, (IUnknown *)&mime_cf,
@@ -2084,16 +2168,13 @@ static void test_BindToObject(int protocol, BOOL emul)
if(FAILED(hres))
return;
- hres = CreateURLMoniker(NULL, urls[test_protocol], &mon);
+ hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon);
ok(SUCCEEDED(hres), "failed to create moniker: %08x\n", hres);
if(FAILED(hres)) {
IBindCtx_Release(bctx);
return;
}
- if(test_protocol == FILE_TEST && INDEX_HTML[7] == '/')
- memmove(INDEX_HTML+7, INDEX_HTML+8, lstrlenW(INDEX_HTML+7)*sizeof(WCHAR));
-
hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
if(SUCCEEDED(hres))
@@ -2128,6 +2209,8 @@ static void test_BindToObject(int protocol, BOOL emul)
SET_EXPECT(OnResponse);
SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
SET_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ SET_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
if(test_protocol == HTTP_TEST)
SET_EXPECT(OnProgress_DOWNLOADINGDATA);
SET_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
@@ -2142,7 +2225,7 @@ static void test_BindToObject(int protocol, BOOL emul)
if (test_protocol == HTTP_TEST && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
{
- trace( "Network unreachable, skipping tests\n" );
+ skip( "Network unreachable, skipping tests\n" );
return;
}
@@ -2193,12 +2276,18 @@ static void test_BindToObject(int protocol, BOOL emul)
CHECK_NOT_CALLED(Obj_OnProgress_CONNECTING);
}
}
- if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
- CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST);
+ if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST) {
+ if(urls[test_protocol] == SHORT_RESPONSE_URL)
+ CLEAR_CALLED(Obj_OnProgress_SENDINGREQUEST);
+ else
+ CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST);
+ }
if(test_protocol == HTTP_TEST)
CHECK_CALLED(OnResponse);
CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ CHECK_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
if(test_protocol == HTTP_TEST)
CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
CLEAR_CALLED(Obj_OnProgress_ENDDOWNLOADDATA);
@@ -2224,18 +2313,106 @@ static void test_BindToObject(int protocol, BOOL emul)
http_is_first = FALSE;
}
+static void test_URLDownloadToFile(DWORD prot, BOOL emul)
+{
+ BOOL res;
+ HRESULT hres;
+
+ init_bind_test(prot, BINDTEST_FILEDWLAPI | (emul ? BINDTEST_EMULATE : 0), TYMED_FILE);
+
+ SET_EXPECT(GetBindInfo);
+ SET_EXPECT(QueryInterface_IInternetProtocol);
+ if(!emulate_protocol) {
+ SET_EXPECT(QueryInterface_IServiceProvider);
+ SET_EXPECT(QueryService_IInternetProtocol);
+ }
+ SET_EXPECT(OnStartBinding);
+ if(emulate_protocol) {
+ SET_EXPECT(Start);
+ SET_EXPECT(UnlockRequest);
+ }else {
+ if(test_protocol == HTTP_TEST) {
+ SET_EXPECT(QueryInterface_IHttpNegotiate);
+ SET_EXPECT(BeginningTransaction);
+ SET_EXPECT(QueryInterface_IHttpNegotiate2);
+ SET_EXPECT(GetRootSecurityId);
+ }
+ if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
+ SET_EXPECT(OnProgress_SENDINGREQUEST);
+ if(test_protocol == HTTP_TEST)
+ SET_EXPECT(OnResponse);
+ SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
+ SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
+ if(test_protocol == HTTP_TEST)
+ SET_EXPECT(OnProgress_DOWNLOADINGDATA);
+ SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
+ SET_EXPECT(OnStopBinding);
+ }
+
+ hres = URLDownloadToFileW(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], dwl_htmlW, 0, &bsc);
+ ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
+
+ CHECK_CALLED(GetBindInfo);
+ CHECK_CALLED(QueryInterface_IInternetProtocol);
+ if(!emulate_protocol) {
+ CHECK_CALLED(QueryInterface_IServiceProvider);
+ CHECK_CALLED(QueryService_IInternetProtocol);
+ }
+ CHECK_CALLED(OnStartBinding);
+ if(emulate_protocol) {
+ CHECK_CALLED(Start);
+ CHECK_CALLED(UnlockRequest);
+ }else {
+ if(test_protocol == HTTP_TEST) {
+ CHECK_CALLED(QueryInterface_IHttpNegotiate);
+ CHECK_CALLED(BeginningTransaction);
+ CHECK_CALLED(QueryInterface_IHttpNegotiate2);
+ CHECK_CALLED(GetRootSecurityId);
+ }
+ if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
+ CHECK_CALLED(OnProgress_SENDINGREQUEST);
+ if(test_protocol == HTTP_TEST)
+ CHECK_CALLED(OnResponse);
+ CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
+ CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
+ if(test_protocol == FILE_TEST)
+ CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
+ if(test_protocol == HTTP_TEST)
+ CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
+ CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
+ CHECK_CALLED(OnStopBinding);
+ }
+
+ res = DeleteFileW(dwl_htmlW);
+ ok(res, "DeleteFile failed: %u\n", GetLastError());
+
+ if(prot != FILE_TEST || emul)
+ return;
+
+ hres = URLDownloadToFileW(NULL, urls[test_protocol], dwl_htmlW, 0, NULL);
+ ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
+
+ res = DeleteFileW(dwl_htmlW);
+ ok(res, "DeleteFile failed: %u\n", GetLastError());
+}
+
static void set_file_url(void)
{
int len;
static const WCHAR wszFile[] = {'f','i','l','e',':','/','/'};
- memcpy(INDEX_HTML, wszFile, sizeof(wszFile));
+ memcpy(file_url, wszFile, sizeof(wszFile));
len = sizeof(wszFile)/sizeof(WCHAR);
- INDEX_HTML[len++] = '/';
- len += GetCurrentDirectoryW(sizeof(INDEX_HTML)/sizeof(WCHAR)-len, INDEX_HTML+len);
- INDEX_HTML[len++] = '\\';
- memcpy(INDEX_HTML+len, wszIndexHtml, sizeof(wszIndexHtml));
+ file_url[len++] = '/';
+ len += GetCurrentDirectoryW(sizeof(file_url)/sizeof(WCHAR)-len, file_url+len);
+ file_url[len++] = '\\';
+ memcpy(file_url+len, wszIndexHtml, sizeof(wszIndexHtml));
+
+ memcpy(INDEX_HTML, wszFile, sizeof(wszIndexHtml));
+ memmove(INDEX_HTML+7, file_url+8, (lstrlenW(file_url+8)+1)*sizeof(WCHAR));
}
static void create_file(void)
@@ -2264,7 +2441,7 @@ static void test_ReportResult(HRESULT exhres)
IUnknown *unk = (void*)0xdeadbeef;
HRESULT hres;
- init_bind_test(ABOUT_TEST, TRUE, FALSE);
+ init_bind_test(ABOUT_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
binding_hres = exhres;
hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
@@ -2282,9 +2459,10 @@ static void test_ReportResult(HRESULT exhres)
hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
if(SUCCEEDED(exhres))
- ok(hres == S_OK, "BindToStorage failed: %08x\n", hres);
+ ok(hres == S_OK || hres == MK_S_ASYNCHRONOUS, "BindToStorage failed: %08x\n", hres);
else
- ok(hres == exhres, "BindToStorage failed: %08x, expected %08x\n", hres, exhres);
+ ok(hres == exhres || hres == MK_S_ASYNCHRONOUS,
+ "BindToStorage failed: %08x, expected %08x or MK_S_ASYNCHRONOUS\n", hres, exhres);
CHECK_CALLED(GetBindInfo);
CHECK_CALLED(QueryInterface_IInternetProtocol);
@@ -2313,7 +2491,8 @@ static void test_BindToStorage_fail(void)
ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
- ok(hres == MK_E_SYNTAX, "hres=%08x, expected INET_E_SYNTAX\n", hres);
+ ok(hres == MK_E_SYNTAX || hres == INET_E_DATA_NOT_AVAILABLE,
+ "hres=%08x, expected MK_E_SYNTAX or INET_E_DATA_NOT_AVAILABLE\n", hres);
IBindCtx_Release(bctx);
@@ -2323,11 +2502,44 @@ static void test_BindToStorage_fail(void)
test_ReportResult(S_FALSE);
}
+static void gecko_installer_workaround(BOOL disable)
+{
+ HKEY hkey;
+ DWORD res;
+
+ static BOOL has_url = FALSE;
+ static char url[2048];
+
+ if(!disable && !has_url)
+ return;
+
+ res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
+ if(res != ERROR_SUCCESS)
+ return;
+
+ if(disable) {
+ DWORD type, size = sizeof(url);
+
+ res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
+ if(res == ERROR_SUCCESS && type == REG_SZ)
+ has_url = TRUE;
+
+ RegDeleteValue(hkey, "GeckoUrl");
+ }else {
+ RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
+ }
+
+ RegCloseKey(hkey);
+}
+
START_TEST(url)
{
+ gecko_installer_workaround(TRUE);
+
complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
complete_event2 = CreateEvent(NULL, FALSE, FALSE, NULL);
thread_id = GetCurrentThreadId();
+ create_file();
test_create();
test_CreateAsyncBindCtx();
@@ -2336,65 +2548,111 @@ START_TEST(url)
test_BindToStorage_fail();
trace("synchronous http test (COM not initialised)...\n");
- test_BindToStorage(HTTP_TEST, FALSE);
+ test_BindToStorage(HTTP_TEST, FALSE, TYMED_ISTREAM);
CoInitialize(NULL);
trace("synchronous http test...\n");
- test_BindToStorage(HTTP_TEST, FALSE);
+ test_BindToStorage(HTTP_TEST, FALSE, TYMED_ISTREAM);
+
+ trace("synchronous http test (to object)...\n");
test_BindToObject(HTTP_TEST, FALSE);
trace("synchronous file test...\n");
- create_file();
- test_BindToStorage(FILE_TEST, FALSE);
+ test_BindToStorage(FILE_TEST, FALSE, TYMED_ISTREAM);
+
+ trace("synchronous file test (to object)...\n");
test_BindToObject(FILE_TEST, FALSE);
- DeleteFileW(wszIndexHtml);
bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
trace("http test...\n");
- test_BindToStorage(HTTP_TEST, FALSE);
+ test_BindToStorage(HTTP_TEST, FALSE, TYMED_ISTREAM);
+
+ trace("http test (to file)...\n");
+ test_BindToStorage(HTTP_TEST, FALSE, TYMED_FILE);
+
+ trace("http test (to object)...\n");
test_BindToObject(HTTP_TEST, FALSE);
trace("http test (short response)...\n");
http_is_first = TRUE;
urls[HTTP_TEST] = SHORT_RESPONSE_URL;
- test_BindToStorage(HTTP_TEST, FALSE);
+ test_BindToStorage(HTTP_TEST, FALSE, TYMED_ISTREAM);
+
+ trace("http test (short response, to object)...\n");
test_BindToObject(HTTP_TEST, FALSE);
trace("emulated http test...\n");
- test_BindToStorage(HTTP_TEST, TRUE);
+ test_BindToStorage(HTTP_TEST, TRUE, TYMED_ISTREAM);
+
+ trace("emulated http test (to object)...\n");
test_BindToObject(HTTP_TEST, TRUE);
+ trace("emulated http test (to file)...\n");
+ test_BindToStorage(HTTP_TEST, TRUE, TYMED_FILE);
+
trace("about test...\n");
- test_BindToStorage(ABOUT_TEST, FALSE);
+ test_BindToStorage(ABOUT_TEST, FALSE, TYMED_ISTREAM);
+
+ trace("about test (to file)...\n");
+ test_BindToStorage(ABOUT_TEST, FALSE, TYMED_FILE);
+
+ trace("about test (to object)...\n");
test_BindToObject(ABOUT_TEST, FALSE);
trace("emulated about test...\n");
- test_BindToStorage(ABOUT_TEST, TRUE);
+ test_BindToStorage(ABOUT_TEST, TRUE, TYMED_ISTREAM);
+
+ trace("emulated about test (to file)...\n");
+ test_BindToStorage(ABOUT_TEST, TRUE, TYMED_FILE);
+
+ trace("emulated about test (to object)...\n");
test_BindToObject(ABOUT_TEST, TRUE);
trace("file test...\n");
- create_file();
- test_BindToStorage(FILE_TEST, FALSE);
+ test_BindToStorage(FILE_TEST, FALSE, TYMED_ISTREAM);
+
+ trace("file test (to file)...\n");
+ test_BindToStorage(FILE_TEST, FALSE, TYMED_FILE);
+
+ trace("file test (to object)...\n");
test_BindToObject(FILE_TEST, FALSE);
- DeleteFileW(wszIndexHtml);
trace("emulated file test...\n");
- set_file_url();
- test_BindToStorage(FILE_TEST, TRUE);
+ test_BindToStorage(FILE_TEST, TRUE, TYMED_ISTREAM);
+
+ trace("emulated file test (to file)...\n");
+ test_BindToStorage(FILE_TEST, TRUE, TYMED_FILE);
+
+ trace("emulated file test (to object)...\n");
test_BindToObject(FILE_TEST, TRUE);
trace("emulated its test...\n");
- test_BindToStorage(ITS_TEST, TRUE);
+ test_BindToStorage(ITS_TEST, TRUE, TYMED_ISTREAM);
+
+ trace("emulated its test (to file)...\n");
+ test_BindToStorage(ITS_TEST, TRUE, TYMED_FILE);
trace("emulated mk test...\n");
- test_BindToStorage(MK_TEST, TRUE);
+ test_BindToStorage(MK_TEST, TRUE, TYMED_ISTREAM);
+
+ trace("test URLDownloadToFile for file protocol...\n");
+ test_URLDownloadToFile(FILE_TEST, FALSE);
+
+ trace("test URLDownloadToFile for emulated file protocol...\n");
+ test_URLDownloadToFile(FILE_TEST, TRUE);
+
+ trace("test URLDownloadToFile for http protocol...\n");
+ test_URLDownloadToFile(HTTP_TEST, FALSE);
trace("test failures...\n");
test_BindToStorage_fail();
+ DeleteFileW(wszIndexHtml);
CloseHandle(complete_event);
CloseHandle(complete_event2);
CoUninitialize();
+
+ gecko_installer_workaround(FALSE);
}
diff --git a/rostests/winetests/urlmon/urlmon.rbuild b/rostests/winetests/urlmon/urlmon.rbuild
index ba4ef138350..07c20c419d5 100644
--- a/rostests/winetests/urlmon/urlmon.rbuild
+++ b/rostests/winetests/urlmon/urlmon.rbuild
@@ -5,18 +5,19 @@
.
0x600
0x600
- wine
- urlmon
- user32
- kernel32
- ole32
- uuid
- ntdll
generated.c
misc.c
protocol.c
stream.c
url.c
testlist.c
+ wine
+ urlmon
+ ole32
+ user32
+ advapi32
+ kernel32
+ uuid
+ ntdll
diff --git a/rostests/winetests/uxtheme/system.c b/rostests/winetests/uxtheme/system.c
index 1fd3d974293..b5f661975fb 100644
--- a/rostests/winetests/uxtheme/system.c
+++ b/rostests/winetests/uxtheme/system.c
@@ -128,7 +128,7 @@ static void test_GetWindowTheme(void)
"Expected E_HANDLE, got 0x%08x\n",
GetLastError());
- /* Only do the bare minumum to get a valid hwnd */
+ /* Only do the bare minimum to get a valid hwnd */
hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
if (!hWnd) return;
@@ -161,7 +161,7 @@ static void test_SetWindowTheme(void)
GetLastError());
}
- /* Only do the bare minumum to get a valid hwnd */
+ /* Only do the bare minimum to get a valid hwnd */
hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
if (!hWnd) return;
@@ -231,7 +231,7 @@ static void test_OpenThemeData(void)
GetLastError());
}
- /* Only do the bare minumum to get a valid hdc */
+ /* Only do the bare minimum to get a valid hdc */
hWnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
if (!hWnd) return;
@@ -417,8 +417,10 @@ static void test_GetCurrentThemeName(void)
/* Given number of characters for the theme name is too large */
SetLastError(0xdeadbeef);
hRes = pGetCurrentThemeName(currentTheme, sizeof(currentTheme), NULL, 0, NULL, 0);
- todo_wine
- ok( hRes == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hRes);
+ if (bThemeActive)
+ ok( hRes == E_POINTER || hRes == S_OK, "Expected E_POINTER or S_OK, got 0x%08x\n", hRes);
+ else
+ ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes);
ok( GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got 0x%08x\n",
GetLastError());
diff --git a/rostests/winetests/uxtheme/uxtheme.rbuild b/rostests/winetests/uxtheme/uxtheme.rbuild
index 1c91cd74204..7e557299de6 100644
--- a/rostests/winetests/uxtheme/uxtheme.rbuild
+++ b/rostests/winetests/uxtheme/uxtheme.rbuild
@@ -1,13 +1,15 @@
+
.
0x600
0x600
+ system.c
+ testlist.c
wine
user32
kernel32
ntdll
- system.c
- testlist.c
+
diff --git a/rostests/winetests/version/info.c b/rostests/winetests/version/info.c
index be1852fc024..3bfc9fb5e40 100644
--- a/rostests/winetests/version/info.c
+++ b/rostests/winetests/version/info.c
@@ -44,6 +44,18 @@
"ERROR_PATH_NOT_FOUND (NT4)/ERROR_FILE_NOT_FOUND (2k3)" \
"expected, got %u\n", GetLastError());
+static void create_file(const CHAR *name)
+{
+ HANDLE file;
+ DWORD written;
+
+ file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
+ WriteFile(file, name, strlen(name), &written, NULL);
+ WriteFile(file, "\n", strlen("\n"), &written, NULL);
+ CloseHandle(file);
+}
+
static void test_info_size(void)
{ DWORD hdl, retval;
char mypath[MAX_PATH] = "";
@@ -153,6 +165,19 @@ static void test_info_size(void)
}
else
trace("skipping GetModuleFileNameA(NULL,..) failed\n");
+
+ create_file("test.txt");
+
+ /* no version info */
+ SetLastError(0xdeadbeef);
+ hdl = 0xcafe;
+ retval = GetFileVersionInfoSizeA("test.txt", &hdl);
+ ok(retval == 0, "Expected 0, got %d\n", retval);
+ ok(hdl == 0, "Expected 0, got %d\n", hdl);
+ ok(GetLastError() == ERROR_RESOURCE_DATA_NOT_FOUND,
+ "Expected ERROR_RESOURCE_DATA_NOT_FOUND, got %d\n", GetLastError());
+
+ DeleteFileA("test.txt");
}
static void VersionDwordLong2String(DWORDLONG Version, LPSTR lpszVerString)
@@ -451,7 +476,8 @@ static void test_VerQueryValue(void)
SetLastError(0xdeadbeef);
ret = VerQueryValue(ver, "String", (LPVOID*)&p, &len);
ok(!ret, "VerQueryValue should fail\n");
- ok(GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND,
+ ok(GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND ||
+ GetLastError() == 0xdeadbeef /* Win9x, NT4, W2K */,
"VerQueryValue returned %u\n", GetLastError());
ok(p == (char *)0xdeadbeef, "expected 0xdeadbeef got %p\n", p);
ok(len == 0, "expected 0 got %x\n", len);
@@ -517,7 +543,8 @@ todo_wine ok(len == 0, "VerQueryValue returned %u, expected 0\n", len);
SetLastError(0xdeadbeef);
ret = VerQueryValue(ver, buf, (LPVOID*)&p, &len);
ok(!ret, "VerQueryValue(%s) succeeded\n", buf);
- ok(GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND,
+ ok(GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND ||
+ GetLastError() == 0xdeadbeef /* Win9x, NT4, W2K */,
"VerQueryValue returned %u\n", GetLastError());
ok(p == (char *)0xdeadbeef, "expected 0xdeadbeef got %p\n", p);
ok(len == 0, "expected 0 got %x\n", len);
diff --git a/rostests/winetests/version/version.rbuild b/rostests/winetests/version/version.rbuild
index 5846259b24a..a90ee2eae51 100644
--- a/rostests/winetests/version/version.rbuild
+++ b/rostests/winetests/version/version.rbuild
@@ -1,15 +1,17 @@
+
.
0x600
0x600
- wine
- version
- kernel32
- ntdll
info.c
install.c
version.rc
testlist.c
+ wine
+ version
+ kernel32
+ ntdll
+