Sweden-Number/dlls/msi/tests/source.c

712 lines
31 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 "wine/test.h"
static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
static UINT (WINAPI *pMsiSourceListGetInfoA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
static UINT (WINAPI *pMsiSourceListAddSourceExA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, DWORD);
static void init_functionpointers(void)
{
HMODULE hmsi = GetModuleHandleA("msi.dll");
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
pMsiSourceListGetInfoA = (void*)GetProcAddress(hmsi, "MsiSourceListGetInfoA");
pMsiSourceListAddSourceExA = (void*)GetProcAddress(hmsi, "MsiSourceListAddSourceExA");
pConvertSidToStringSidA = (void*)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
}
/* copied from dlls/msi/registry.c */
static BOOL squash_guid(LPCWSTR in, LPWSTR out)
{
DWORD i,n=1;
GUID guid;
if (FAILED(CLSIDFromString((LPOLESTR)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, (LPOLESTR)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 void get_user_sid(LPSTR *usersid)
{
HANDLE token;
BYTE buf[1024];
DWORD size;
PTOKEN_USER user;
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
size = sizeof(buf);
GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
user = (PTOKEN_USER)buf;
pConvertSidToStringSidA(user->User.Sid, usersid);
}
static void test_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;
DWORD size;
create_test_guid(prodcode, prod_squashed);
get_user_sid(&usersid);
/* 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);
/* 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 */
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
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 = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
res = RegCreateKeyA(userkey, "SourceList", &hkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* SourceList key exists */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(size == 0, "Expected 0, got %d\n", size);
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, "Expected ERROR_SUCCESS, got %d\n", r);
ok(size == 11, "Expected 11, got %d\n", size);
/* read the value, don't change size */
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 = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, "", NULL, &size);
ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
/* nonexistent property now that product key exists */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, "nonexistent", NULL, &size);
ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
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 = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PRODUCT, "nonexistent", NULL, &size);
ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
/* invalid option now that product key exists */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(size == 11, "Expected 11, got %d\n", size);
RegDeleteValueA(hkey, "nonexistent");
RegDeleteValueA(hkey, "PackageName");
RegDeleteKeyA(hkey, "");
RegDeleteKeyA(userkey, "");
RegCloseKey(hkey);
RegCloseKey(userkey);
/* try a patch */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
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 = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
res = RegCreateKeyA(userkey, "SourceList", &hkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* SourceList key exists */
size = 0xdeadbeef;
r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(size == 0, "Expected 0, got %d\n", size);
RegDeleteKeyA(hkey, "");
RegDeleteKeyA(userkey, "");
RegCloseKey(hkey);
RegCloseKey(userkey);
}
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;
HKEY url, net;
DWORD size;
if (!pMsiSourceListAddSourceExA)
{
skip("Skipping MsiSourceListAddSourceEx tests\n");
return;
}
create_test_guid(prodcode, prod_squashed);
get_user_sid(&usersid);
/* 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 = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* 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 = RegCreateKeyA(prodkey, "SourceList", &hkey);
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 = RegOpenKeyA(prodkey, "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);
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 = RegOpenKeyA(prodkey, "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);
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 */
/* 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 = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* 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 = RegCreateKeyA(prodkey, "SourceList", &hkey);
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 = RegOpenKeyA(prodkey, "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);
RegCloseKey(url);
RegCloseKey(prodkey);
HeapFree(GetProcessHeap(), 0, usersid);
}
START_TEST(source)
{
init_functionpointers();
test_MsiSourceListGetInfo();
test_MsiSourceListAddSourceEx();
}