3491 lines
150 KiB
C
3491 lines
150 KiB
C
/*
|
|
* Tests for MSI Source functions
|
|
*
|
|
* Copyright (C) 2006 James Hawkins
|
|
*
|
|
* 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 _WIN32_MSI 300
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <windows.h>
|
|
#include <msiquery.h>
|
|
#include <msidefs.h>
|
|
#include <msi.h>
|
|
#include <sddl.h>
|
|
#include <secext.h>
|
|
|
|
#include "wine/test.h"
|
|
|
|
static BOOL is_wow64;
|
|
|
|
static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
|
|
static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
|
|
static BOOLEAN (WINAPI *pGetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG);
|
|
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
|
|
|
|
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)
|
|
{
|
|
HMODULE hmsi = GetModuleHandleA("msi.dll");
|
|
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
|
|
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
|
|
HMODULE hsecur32 = LoadLibraryA("secur32.dll");
|
|
|
|
#define GET_PROC(dll, func) \
|
|
p ## func = (void *)GetProcAddress(dll, #func); \
|
|
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)
|
|
GET_PROC(hadvapi32, RegDeleteKeyExA)
|
|
GET_PROC(hkernel32, IsWow64Process)
|
|
GET_PROC(hsecur32, GetUserNameExA)
|
|
|
|
#undef GET_PROC
|
|
}
|
|
|
|
/* copied from dlls/msi/registry.c */
|
|
static BOOL squash_guid(LPCWSTR in, LPWSTR out)
|
|
{
|
|
DWORD i,n=1;
|
|
GUID guid;
|
|
|
|
if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
|
|
return FALSE;
|
|
|
|
for(i=0; i<8; i++)
|
|
out[7-i] = in[n++];
|
|
n++;
|
|
for(i=0; i<4; i++)
|
|
out[11-i] = in[n++];
|
|
n++;
|
|
for(i=0; i<4; i++)
|
|
out[15-i] = in[n++];
|
|
n++;
|
|
for(i=0; i<2; i++)
|
|
{
|
|
out[17+i*2] = in[n++];
|
|
out[16+i*2] = in[n++];
|
|
}
|
|
n++;
|
|
for( ; i<8; i++)
|
|
{
|
|
out[17+i*2] = in[n++];
|
|
out[16+i*2] = in[n++];
|
|
}
|
|
out[32]=0;
|
|
return TRUE;
|
|
}
|
|
|
|
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
|
|
{
|
|
WCHAR guidW[MAX_PATH];
|
|
WCHAR squashedW[MAX_PATH];
|
|
GUID guid;
|
|
HRESULT hr;
|
|
int size;
|
|
|
|
hr = CoCreateGuid(&guid);
|
|
ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
|
|
|
|
size = StringFromGUID2(&guid, guidW, MAX_PATH);
|
|
ok(size == 39, "Expected 39, got %d\n", hr);
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
|
|
squash_guid(guidW, squashedW);
|
|
WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
|
|
}
|
|
|
|
static char *get_user_sid(void)
|
|
{
|
|
HANDLE token;
|
|
DWORD size = 0;
|
|
TOKEN_USER *user;
|
|
char *usersid = NULL;
|
|
|
|
if (!pConvertSidToStringSidA)
|
|
{
|
|
win_skip("ConvertSidToStringSidA is not available\n");
|
|
return NULL;
|
|
}
|
|
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
|
|
GetTokenInformation(token, TokenUser, NULL, size, &size);
|
|
|
|
user = HeapAlloc(GetProcessHeap(), 0, size);
|
|
GetTokenInformation(token, TokenUser, user, size, &size);
|
|
pConvertSidToStringSidA(user->User.Sid, &usersid);
|
|
HeapFree(GetProcessHeap(), 0, user);
|
|
|
|
CloseHandle(token);
|
|
return usersid;
|
|
}
|
|
|
|
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];
|
|
CHAR prod_squashed[MAX_PATH];
|
|
CHAR keypath[MAX_PATH*2];
|
|
CHAR value[MAX_PATH];
|
|
LPSTR usersid;
|
|
LPCSTR data;
|
|
LONG res;
|
|
UINT r;
|
|
HKEY userkey, hkey, media;
|
|
DWORD size;
|
|
|
|
if (!pMsiSourceListGetInfoA)
|
|
{
|
|
win_skip("Skipping MsiSourceListGetInfoA tests\n");
|
|
return;
|
|
}
|
|
|
|
create_test_guid(prodcode, prod_squashed);
|
|
if (!(usersid = get_user_sid()))
|
|
{
|
|
skip("User SID not available -> skipping MsiSourceListGetInfoA tests\n");
|
|
return;
|
|
}
|
|
|
|
/* NULL szProductCodeOrPatchCode */
|
|
r = pMsiSourceListGetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* empty szProductCodeOrPatchCode */
|
|
r = pMsiSourceListGetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* garbage szProductCodeOrPatchCode */
|
|
r = pMsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* guid without brackets */
|
|
r = pMsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* guid with brackets */
|
|
r = pMsiSourceListGetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
|
|
|
|
/* same length as guid, but random */
|
|
r = pMsiSourceListGetInfoA("ADKD-2KSDFF2-DKK1KNFJASD9GLKWME-1I3KAD", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* invalid context */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_NONE,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* another invalid context */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALLUSERMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* yet another invalid context */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALL,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* mix two valid contexts */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* invalid option */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
4, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
|
|
|
|
/* NULL property */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, NULL, NULL, NULL);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* empty property */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, "", NULL, NULL);
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
|
|
|
|
/* value is non-NULL while size is NULL */
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, NULL);
|
|
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 || r == ERROR_INVALID_PARAMETER,
|
|
"Expected ERROR_UNKNOWN_PRODUCT or ERROR_INVALID_PARAMETER, 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 */
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
|
|
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
res = RegCreateKeyA(userkey, "SourceList", &hkey);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
/* SourceList key exists */
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
ok(size == 0, "Expected 0, got %d\n", size);
|
|
ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
|
|
|
|
data = "msitest.msi";
|
|
res = RegSetValueExA(hkey, "PackageName", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
/* PackageName value exists */
|
|
size = 0xdeadbeef;
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
|
|
ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER,
|
|
"Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
ok(size == 11 || r != ERROR_SUCCESS, "Expected 11, got %d\n", size);
|
|
|
|
/* read the value, don't change size */
|
|
size = 11;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, 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 == 11, "Expected 11, got %d\n", size);
|
|
|
|
/* read the value, fix size */
|
|
size++;
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
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);
|
|
|
|
/* empty property now that product key exists */
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, "", value, &size);
|
|
ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
|
|
ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
/* nonexistent property now that product key exists */
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, "nonexistent", value, &size);
|
|
ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
|
|
ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
data = "tester";
|
|
res = RegSetValueExA(hkey, "nonexistent", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
/* nonexistent property now that nonexistent value exists */
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, "nonexistent", value, &size);
|
|
ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
|
|
ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
/* invalid option now that product key exists */
|
|
size = MAX_PATH;
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
4, INSTALLPROPERTY_PACKAGENAME, value, &size);
|
|
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, "");
|
|
RegDeleteKeyA(userkey, "");
|
|
RegCloseKey(hkey);
|
|
RegCloseKey(userkey);
|
|
|
|
/* try a patch */
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, value, &size);
|
|
ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
|
|
ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\");
|
|
lstrcatA(keypath, prod_squashed);
|
|
|
|
res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
/* patch key exists
|
|
* NOTE: using prodcode guid, but it really doesn't matter
|
|
*/
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, value, &size);
|
|
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
|
|
ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
res = RegCreateKeyA(userkey, "SourceList", &hkey);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
/* SourceList key exists */
|
|
size = MAX_PATH;
|
|
lstrcpyA(value, "aaa");
|
|
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, 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);
|
|
|
|
RegDeleteKeyA(hkey, "");
|
|
RegDeleteKeyA(userkey, "");
|
|
RegCloseKey(hkey);
|
|
RegCloseKey(userkey);
|
|
LocalFree(usersid);
|
|
}
|
|
|
|
static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
|
|
{
|
|
if (pRegDeleteKeyExA)
|
|
return pRegDeleteKeyExA( key, subkey, access, 0 );
|
|
return RegDeleteKeyA( key, subkey );
|
|
}
|
|
|
|
static void test_MsiSourceListAddSourceEx(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;
|
|
DWORD size;
|
|
REGSAM access = KEY_ALL_ACCESS;
|
|
|
|
if (!pMsiSourceListAddSourceExA)
|
|
{
|
|
win_skip("Skipping MsiSourceListAddSourceExA tests\n");
|
|
return;
|
|
}
|
|
|
|
create_test_guid(prodcode, prod_squashed);
|
|
if (!(usersid = get_user_sid()))
|
|
{
|
|
skip("User SID not available -> skipping MsiSourceListAddSourceExA tests\n");
|
|
return;
|
|
}
|
|
|
|
if (is_wow64)
|
|
access |= KEY_WOW64_64KEY;
|
|
|
|
/* GetLastError is not set by the function */
|
|
|
|
/* NULL szProductCodeOrPatchCode */
|
|
r = pMsiSourceListAddSourceExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* empty szProductCodeOrPatchCode */
|
|
r = pMsiSourceListAddSourceExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* garbage szProductCodeOrPatchCode */
|
|
r = pMsiSourceListAddSourceExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* guid without brackets */
|
|
r = pMsiSourceListAddSourceExA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* guid with brackets */
|
|
r = pMsiSourceListAddSourceExA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
|
|
|
|
/* MSIINSTALLCONTEXT_USERUNMANAGED */
|
|
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
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 = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
|
|
|
|
res = RegCreateKeyA(userkey, "SourceList", &url);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
RegCloseKey(url);
|
|
|
|
/* SourceList key exists */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
res = RegOpenKeyA(userkey, "SourceList\\URL", &url);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
/* add another source, index 0 */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
|
|
ok(size == 9, "Expected 9, got %d\n", size);
|
|
|
|
/* add another source, index 1 */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "third/", 1);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
|
|
ok(size == 7, "Expected 7, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
|
|
ok(size == 9, "Expected 9, got %d\n", size);
|
|
|
|
/* add another source, index > N */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "last/", 5);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
|
|
ok(size == 7, "Expected 7, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
|
|
ok(size == 9, "Expected 9, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "4", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
|
|
ok(size == 6, "Expected 6, got %d\n", size);
|
|
|
|
/* just MSISOURCETYPE_NETWORK */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSISOURCETYPE_NETWORK, "source", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
res = RegOpenKeyA(userkey, "SourceList\\Net", &net);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(net, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
|
|
ok(size == 8, "Expected 8, got %d\n", size);
|
|
|
|
/* just MSISOURCETYPE_URL */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSISOURCETYPE_URL, "source", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
|
|
ok(size == 7, "Expected 7, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
|
|
ok(size == 9, "Expected 9, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "4", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
|
|
ok(size == 6, "Expected 6, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "5", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "source/"), "Expected 'source/', got %s\n", value);
|
|
ok(size == 8, "Expected 8, got %d\n", size);
|
|
|
|
/* NULL szUserSid */
|
|
r = pMsiSourceListAddSourceExA(prodcode, NULL,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSISOURCETYPE_NETWORK, "nousersid", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(net, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
|
|
ok(size == 8, "Expected 8, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(net, "2", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "nousersid\\"), "Expected 'nousersid\\', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
/* invalid options, must have source type */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PRODUCT, "source", 0);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSICODE_PATCH, "source", 0);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* NULL szSource */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSISOURCETYPE_URL, NULL, 1);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* empty szSource */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
MSISOURCETYPE_URL, "", 1);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
/* MSIINSTALLCONTEXT_USERMANAGED, non-NULL szUserSid */
|
|
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
goto machine_tests;
|
|
}
|
|
|
|
/* product key exists */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
|
|
|
|
res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
RegCloseKey(hkey);
|
|
|
|
/* SourceList exists */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_USERMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
RegCloseKey(url);
|
|
|
|
/* MSIINSTALLCONTEXT_USERMANAGED, NULL szUserSid */
|
|
|
|
r = pMsiSourceListAddSourceExA(prodcode, NULL,
|
|
MSIINSTALLCONTEXT_USERMANAGED,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
|
|
ok(size == 9, "Expected 9, got %d\n", size);
|
|
|
|
RegCloseKey(url);
|
|
RegCloseKey(prodkey);
|
|
|
|
/* MSIINSTALLCONTEXT_MACHINE */
|
|
|
|
machine_tests:
|
|
/* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
|
|
r = pMsiSourceListAddSourceExA(prodcode, usersid,
|
|
MSIINSTALLCONTEXT_MACHINE,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
r = pMsiSourceListAddSourceExA(prodcode, NULL,
|
|
MSIINSTALLCONTEXT_MACHINE,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
|
|
lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
|
|
lstrcatA(keypath, prod_squashed);
|
|
|
|
res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
LocalFree(usersid);
|
|
return;
|
|
}
|
|
|
|
/* product key exists */
|
|
r = pMsiSourceListAddSourceExA(prodcode, NULL,
|
|
MSIINSTALLCONTEXT_MACHINE,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
|
|
|
|
res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
RegCloseKey(hkey);
|
|
|
|
/* SourceList exists */
|
|
r = pMsiSourceListAddSourceExA(prodcode, NULL,
|
|
MSIINSTALLCONTEXT_MACHINE,
|
|
MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
|
|
res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
size = MAX_PATH;
|
|
res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
|
|
ok(size == 11, "Expected 11, got %d\n", size);
|
|
|
|
RegCloseKey(url);
|
|
RegCloseKey(prodkey);
|
|
LocalFree(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;
|
|
REGSAM access = KEY_ALL_ACCESS;
|
|
|
|
if (!pMsiSourceListEnumSourcesA)
|
|
{
|
|
win_skip("MsiSourceListEnumSourcesA is not available\n");
|
|
return;
|
|
}
|
|
|
|
create_test_guid(prodcode, prod_squashed);
|
|
if (!(usersid = get_user_sid()))
|
|
{
|
|
skip("User SID not available -> skipping MsiSourceListEnumSourcesA tests\n");
|
|
return;
|
|
}
|
|
|
|
if (is_wow64)
|
|
access |= KEY_WOW64_64KEY;
|
|
|
|
/* 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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
goto machine_tests;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL);
|
|
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");
|
|
delete_key(url, "", access);
|
|
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 = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL);
|
|
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");
|
|
delete_key(net, "", access);
|
|
RegCloseKey(net);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(userkey, "", access);
|
|
RegCloseKey(userkey);
|
|
|
|
/* MSIINSTALLCONTEXT_MACHINE */
|
|
|
|
machine_tests:
|
|
/* 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 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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
LocalFree(usersid);
|
|
return;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL);
|
|
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");
|
|
delete_key(url, "", access);
|
|
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 = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL);
|
|
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");
|
|
delete_key(net, "", access);
|
|
RegCloseKey(net);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(prodkey, "", access);
|
|
RegCloseKey(prodkey);
|
|
LocalFree(usersid);
|
|
}
|
|
|
|
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;
|
|
REGSAM access = KEY_ALL_ACCESS;
|
|
|
|
if (!pMsiSourceListSetInfoA)
|
|
{
|
|
win_skip("MsiSourceListSetInfoA is not available\n");
|
|
return;
|
|
}
|
|
|
|
create_test_guid(prodcode, prod_squashed);
|
|
if (!(usersid = get_user_sid()))
|
|
{
|
|
skip("User SID not available -> skipping MsiSourceListSetInfoA tests\n");
|
|
return;
|
|
}
|
|
|
|
if (is_wow64)
|
|
access |= KEY_WOW64_64KEY;
|
|
|
|
/* 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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
goto machine_tests;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegOpenKeyExA(source, "Media", 0, access, &media);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
CHECK_REG_STR(media, "MediaPackage", "path");
|
|
|
|
RegDeleteValueA(media, "MediaPackage");
|
|
delete_key(media, "", access);
|
|
RegCloseKey(media);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(userkey, "", access);
|
|
RegCloseKey(userkey);
|
|
|
|
/* MSIINSTALLCONTEXT_MACHINE */
|
|
|
|
machine_tests:
|
|
lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
|
|
lstrcatA(keypath, prod_squashed);
|
|
|
|
res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
LocalFree(usersid);
|
|
return;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegOpenKeyExA(source, "Media", 0, access, &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");
|
|
delete_key(media, "", access);
|
|
RegCloseKey(media);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(prodkey, "", access);
|
|
RegCloseKey(prodkey);
|
|
LocalFree(usersid);
|
|
}
|
|
|
|
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;
|
|
REGSAM access = KEY_ALL_ACCESS;
|
|
|
|
if (!pMsiSourceListAddMediaDiskA)
|
|
{
|
|
win_skip("MsiSourceListAddMediaDiskA is not available\n");
|
|
return;
|
|
}
|
|
|
|
create_test_guid(prodcode, prod_squashed);
|
|
if (!(usersid = get_user_sid()))
|
|
{
|
|
skip("User SID not available -> skipping MsiSourceListAddMediaDiskA tests\n");
|
|
return;
|
|
}
|
|
|
|
if (is_wow64)
|
|
access |= KEY_WOW64_64KEY;
|
|
|
|
/* 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, szVolumeLabel 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, szVolumeLabel 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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
goto machine_tests;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegOpenKeyExA(source, "Media", 0, access, &media);
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
CHECK_REG_STR(media, "1", "label;prompt");
|
|
|
|
RegDeleteValueA(media, "1");
|
|
delete_key(media, "", access);
|
|
RegCloseKey(media);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(userkey, "", access);
|
|
RegCloseKey(userkey);
|
|
|
|
/* MSIINSTALLCONTEXT_MACHINE */
|
|
|
|
machine_tests:
|
|
lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
|
|
lstrcatA(keypath, prod_squashed);
|
|
|
|
res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
LocalFree(usersid);
|
|
return;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegOpenKeyExA(source, "Media", 0, access, &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");
|
|
delete_key(media, "", access);
|
|
RegCloseKey(media);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(prodkey, "", access);
|
|
RegCloseKey(prodkey);
|
|
LocalFree(usersid);
|
|
}
|
|
|
|
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, media, source;
|
|
DWORD labelsz, promptsz, val, id;
|
|
LPSTR usersid;
|
|
LONG res;
|
|
UINT r;
|
|
REGSAM access = KEY_ALL_ACCESS;
|
|
|
|
if (!pMsiSourceListEnumMediaDisksA)
|
|
{
|
|
win_skip("MsiSourceListEnumMediaDisksA is not available\n");
|
|
return;
|
|
}
|
|
|
|
create_test_guid(prodcode, prod_squashed);
|
|
if (!(usersid = get_user_sid()))
|
|
{
|
|
skip("User SID not available -> skipping MsiSourceListEnumMediaDisksA tests\n");
|
|
return;
|
|
}
|
|
|
|
if (is_wow64)
|
|
access |= KEY_WOW64_64KEY;
|
|
|
|
/* GetLastError is not set by the function */
|
|
|
|
/* NULL szProductCodeOrPatchCode */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 */
|
|
labelsz = sizeof(label);
|
|
promptsz = sizeof(prompt);
|
|
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 || r == ERROR_INVALID_PARAMETER,
|
|
"Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
if (r == ERROR_SUCCESS)
|
|
{
|
|
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_SUCCESS || r == ERROR_INVALID_PARAMETER,
|
|
"Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
if (r == ERROR_SUCCESS)
|
|
{
|
|
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);
|
|
}
|
|
else if (r == ERROR_INVALID_PARAMETER)
|
|
{
|
|
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 || r == ERROR_INVALID_PARAMETER,
|
|
"Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
if (r == ERROR_SUCCESS)
|
|
{
|
|
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 || r == ERROR_INVALID_PARAMETER,
|
|
"Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
|
|
if (r == ERROR_SUCCESS)
|
|
{
|
|
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 || r == ERROR_INVALID_PARAMETER, "Expected ERROR_SUCCESS, got %d\n", r);
|
|
if (r == ERROR_SUCCESS)
|
|
{
|
|
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);
|
|
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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
goto machine_tests;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegCreateKeyExA(source, "Media", 0, NULL, 0, access, NULL, &media, NULL);
|
|
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");
|
|
delete_key(media, "", access);
|
|
RegCloseKey(media);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(userkey, "", access);
|
|
RegCloseKey(userkey);
|
|
|
|
/* MSIINSTALLCONTEXT_MACHINE */
|
|
|
|
machine_tests:
|
|
lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
|
|
lstrcatA(keypath, prod_squashed);
|
|
|
|
res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
LocalFree(usersid);
|
|
return;
|
|
}
|
|
|
|
/* 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 = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegCreateKeyExA(source, "Media", 0, NULL, 0, access, NULL, &media, NULL);
|
|
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");
|
|
delete_key(media, "", access);
|
|
RegCloseKey(media);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(prodkey, "", access);
|
|
RegCloseKey(prodkey);
|
|
LocalFree(usersid);
|
|
}
|
|
|
|
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, net, source;
|
|
DWORD size;
|
|
REGSAM access = KEY_ALL_ACCESS;
|
|
|
|
if (!pMsiSourceListAddSourceA)
|
|
{
|
|
win_skip("Skipping MsiSourceListAddSourceA tests\n");
|
|
return;
|
|
}
|
|
|
|
create_test_guid(prodcode, prod_squashed);
|
|
if (!(usersid = get_user_sid()))
|
|
{
|
|
skip("User SID not available -> skipping MsiSourceListAddSourceA tests\n");
|
|
return;
|
|
}
|
|
|
|
/* MACHINENAME\username */
|
|
size = MAX_PATH;
|
|
if (pGetUserNameExA != NULL)
|
|
pGetUserNameExA(NameSamCompatible, username, &size);
|
|
else
|
|
{
|
|
GetComputerNameA(username, &size);
|
|
lstrcatA(username, "\\");
|
|
ptr = username + lstrlenA(username);
|
|
size = MAX_PATH - (ptr - username);
|
|
GetUserNameA(ptr, &size);
|
|
}
|
|
trace("username: %s\n", username);
|
|
|
|
if (is_wow64)
|
|
access |= KEY_WOW64_64KEY;
|
|
|
|
/* 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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
goto userunmanaged_tests;
|
|
}
|
|
|
|
/* user product key exists */
|
|
r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
|
|
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
|
|
|
|
res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegOpenKeyExA(source, "Net", 0, access, &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");
|
|
delete_key(net, "", access);
|
|
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 = RegOpenKeyExA(source, "Net", 0, access, &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");
|
|
delete_key(net, "", access);
|
|
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 = RegOpenKeyExA(source, "Net", 0, access, &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");
|
|
delete_key(net, "", access);
|
|
RegCloseKey(net);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(userkey, "", access);
|
|
RegCloseKey(userkey);
|
|
|
|
/* MSIINSTALLCONTEXT_USERUNMANAGED */
|
|
|
|
userunmanaged_tests:
|
|
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);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
goto machine_tests;
|
|
}
|
|
|
|
/* 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 */
|
|
|
|
machine_tests:
|
|
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 = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
skip("Product key creation failed with error code %u\n", res);
|
|
LocalFree(usersid);
|
|
return;
|
|
}
|
|
|
|
/* machine product key exists */
|
|
r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source");
|
|
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
|
|
|
|
res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
|
|
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 = RegOpenKeyExA(source, "Net", 0, access, &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");
|
|
delete_key(net, "", access);
|
|
RegCloseKey(net);
|
|
delete_key(source, "", access);
|
|
RegCloseKey(source);
|
|
delete_key(prodkey, "", access);
|
|
RegCloseKey(prodkey);
|
|
LocalFree(usersid);
|
|
}
|
|
|
|
START_TEST(source)
|
|
{
|
|
init_functionpointers();
|
|
|
|
if (pIsWow64Process)
|
|
pIsWow64Process(GetCurrentProcess(), &is_wow64);
|
|
|
|
test_MsiSourceListGetInfo();
|
|
test_MsiSourceListAddSourceEx();
|
|
test_MsiSourceListEnumSources();
|
|
test_MsiSourceListSetInfo();
|
|
test_MsiSourceListAddMediaDisk();
|
|
test_MsiSourceListEnumMediaDisks();
|
|
test_MsiSourceListAddSource();
|
|
}
|