[MSI_WINETEST]
[reactos.git] / rostests / winetests / msi / package.c
index ddb3522..8cf8f27 100644 (file)
 #include <msi.h>
 #include <msiquery.h>
 #include <srrestoreptapi.h>
+#include <shlobj.h>
 
 #include "wine/test.h"
 
+static BOOL is_wow64;
 static const char msifile[] = "winetest-package.msi";
-char CURR_DIR[MAX_PATH];
+static char CURR_DIR[MAX_PATH];
 
 static UINT (WINAPI *pMsiApplyMultiplePatchesA)(LPCSTR, LPCSTR, LPCSTR);
+static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
+static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
 
 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
+static BOOL (WINAPI *pGetTokenInformation)( HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD );
+static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
+static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
+static LONG (WINAPI *pRegDeleteKeyExW)(HKEY, LPCWSTR, REGSAM, DWORD);
+static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
+static void (WINAPI *pGetSystemInfo)(LPSYSTEM_INFO);
+static void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO);
+static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR, UINT);
 
 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
@@ -44,14 +56,26 @@ static void init_functionpointers(void)
 {
     HMODULE hmsi = GetModuleHandleA("msi.dll");
     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
+    HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
+    HMODULE hshell32 = GetModuleHandleA("shell32.dll");
     HMODULE hsrclient;
 
 #define GET_PROC(mod, func) \
     p ## func = (void*)GetProcAddress(mod, #func);
 
     GET_PROC(hmsi, MsiApplyMultiplePatchesA);
+    GET_PROC(hmsi, MsiGetComponentPathExA);
+    GET_PROC(hshell32, SHGetFolderPathA);
 
     GET_PROC(hadvapi32, ConvertSidToStringSidA);
+    GET_PROC(hadvapi32, GetTokenInformation);
+    GET_PROC(hadvapi32, OpenProcessToken);
+    GET_PROC(hadvapi32, RegDeleteKeyExA)
+    GET_PROC(hadvapi32, RegDeleteKeyExW)
+    GET_PROC(hkernel32, IsWow64Process)
+    GET_PROC(hkernel32, GetNativeSystemInfo)
+    GET_PROC(hkernel32, GetSystemInfo)
+    GET_PROC(hkernel32, GetSystemWow64DirectoryA)
 
     hsrclient = LoadLibraryA("srclient.dll");
     GET_PROC(hsrclient, SRRemoveRestorePoint);
@@ -59,33 +83,58 @@ static void init_functionpointers(void)
 #undef GET_PROC
 }
 
+static BOOL is_process_limited(void)
+{
+    HANDLE token;
+
+    if (!pOpenProcessToken || !pGetTokenInformation) return FALSE;
+
+    if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
+    {
+        BOOL ret;
+        TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
+        DWORD size;
+
+        ret = pGetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
+        CloseHandle(token);
+        return (ret && type == TokenElevationTypeLimited);
+    }
+    return FALSE;
+}
 
-static LPSTR get_user_sid(LPSTR *usersid)
+static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
+{
+    if (pRegDeleteKeyExA)
+        return pRegDeleteKeyExA( key, subkey, access, 0 );
+    return RegDeleteKeyA( key, subkey );
+}
+
+static char *get_user_sid(void)
 {
     HANDLE token;
-    BYTE buf[1024];
-    DWORD size;
-    PTOKEN_USER user;
+    DWORD size = 0;
+    TOKEN_USER *user;
+    char *usersid = NULL;
 
     if (!pConvertSidToStringSidA)
     {
         win_skip("ConvertSidToStringSidA is not available\n");
         return NULL;
     }
-
-    *usersid = NULL;
     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
-    size = sizeof(buf);
-    GetTokenInformation(token, TokenUser, buf, size, &size);
-    user = (PTOKEN_USER)buf;
-    pConvertSidToStringSidA(user->User.Sid, usersid);
-    ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError());
+    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;
+    return usersid;
 }
 
 /* RegDeleteTreeW from dlls/advapi32/registry.c */
-static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
+static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey, REGSAM access)
 {
     LONG ret;
     DWORD dwMaxSubkeyLen, dwMaxValueLen;
@@ -95,7 +144,7 @@ static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
 
     if(lpszSubKey)
     {
-        ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
+        ret = RegOpenKeyExW(hKey, lpszSubKey, 0, access, &hSubKey);
         if (ret) return ret;
     }
 
@@ -123,12 +172,17 @@ static LSTATUS package_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
         if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
                           NULL, NULL, NULL)) break;
 
-        ret = package_RegDeleteTreeW(hSubKey, lpszName);
+        ret = package_RegDeleteTreeW(hSubKey, lpszName, access);
         if (ret) goto cleanup;
     }
 
     if (lpszSubKey)
-        ret = RegDeleteKeyW(hKey, lpszSubKey);
+    {
+        if (pRegDeleteKeyExW)
+            ret = pRegDeleteKeyExW(hKey, lpszSubKey, access, 0);
+        else
+            ret = RegDeleteKeyW(hKey, lpszSubKey);
+    }
     else
         while (TRUE)
         {
@@ -153,7 +207,7 @@ static BOOL squash_guid(LPCWSTR in, LPWSTR out)
     DWORD i,n=1;
     GUID guid;
 
-    if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
+    if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
         return FALSE;
 
     for(i=0; i<8; i++)
@@ -210,6 +264,10 @@ static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
     CHAR path[MAX_PATH];
     LPCSTR prod = NULL;
     HKEY hkey;
+    REGSAM access = KEY_ALL_ACCESS;
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
     squash_guid(guidW, squashedW);
@@ -248,7 +306,7 @@ static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
                 "7D2F387510109040002000060BECB6AB", usersid);
     }
 
-    RegCreateKeyA(HKEY_LOCAL_MACHINE, comppath, &hkey);
+    RegCreateKeyExA(HKEY_LOCAL_MACHINE, comppath, 0, NULL, 0, access, NULL, &hkey, NULL);
 
     lstrcpyA(path, CURR_DIR);
     lstrcatA(path, "\\");
@@ -257,7 +315,7 @@ static void set_component_path(LPCSTR filename, MSIINSTALLCONTEXT context,
     RegSetValueExA(hkey, prod, 0, REG_SZ, (LPBYTE)path, lstrlenA(path));
     RegCloseKey(hkey);
 
-    RegCreateKeyA(HKEY_LOCAL_MACHINE, prodpath, &hkey);
+    RegCreateKeyExA(HKEY_LOCAL_MACHINE, prodpath, 0, NULL, 0, access, NULL, &hkey, NULL);
     RegCloseKey(hkey);
 }
 
@@ -269,6 +327,10 @@ static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR
     CHAR squashed[MAX_PATH];
     CHAR comppath[MAX_PATH];
     CHAR prodpath[MAX_PATH];
+    REGSAM access = KEY_ALL_ACCESS;
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     MultiByteToWideChar(CP_ACP, 0, guid, -1, guidW, MAX_PATH);
     squash_guid(guidW, squashedW);
@@ -305,10 +367,10 @@ static void delete_component_path(LPCSTR guid, MSIINSTALLCONTEXT context, LPSTR
     }
 
     MultiByteToWideChar(CP_ACP, 0, comppath, -1, substrW, MAX_PATH);
-    package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW);
+    package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
 
     MultiByteToWideChar(CP_ACP, 0, prodpath, -1, substrW, MAX_PATH);
-    package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW);
+    package_RegDeleteTreeW(HKEY_LOCAL_MACHINE, substrW, access);
 }
 
 static UINT do_query(MSIHANDLE hdb, const char *query, MSIHANDLE *phrec)
@@ -574,10 +636,6 @@ make_add_entry(appsearch,
                "INSERT INTO `AppSearch` "
                "(`Property`, `Signature_`) VALUES( %s )")
 
-make_add_entry(reglocator,
-               "INSERT INTO `RegLocator` "
-               "(`Signature_`, `Root`, `Key`, `Name`, `Type`) VALUES( %s )")
-
 make_add_entry(signature,
                "INSERT INTO `Signature` "
                "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`,"
@@ -616,6 +674,23 @@ make_add_entry(inilocator,
                "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) "
                "VALUES( %s )")
 
+static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
+                                  const char *name, UINT type )
+{
+    const char insert[] =
+        "INSERT INTO `RegLocator` (`Signature_`, `Root`, `Key`, `Name`, `Type`) "
+        "VALUES( '%s', %u, '%s', '%s', %u )";
+    char *query;
+    UINT sz, r;
+
+    sz = strlen( sig ) + 10 + strlen( path ) + strlen( name ) + 10 + sizeof( insert );
+    query = HeapAlloc( GetProcessHeap(), 0, sz );
+    sprintf( query, insert, sig, root, path, name, type );
+    r = run_query( hdb, query );
+    HeapFree( GetProcessHeap(), 0, query );
+    return r;
+}
+
 static UINT set_summary_info(MSIHANDLE hdb)
 {
     UINT res;
@@ -670,7 +745,7 @@ static MSIHANDLE create_package_db(void)
 
     /* create an empty database */
     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
-    ok( res == ERROR_SUCCESS , "Failed to create database\n" );
+    ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res );
     if( res != ERROR_SUCCESS )
         return hdb;
 
@@ -678,6 +753,7 @@ static MSIHANDLE create_package_db(void)
     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
 
     res = set_summary_info(hdb);
+    ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
 
     res = run_query( hdb,
             "CREATE TABLE `Directory` ( "
@@ -690,22 +766,29 @@ static MSIHANDLE create_package_db(void)
     return hdb;
 }
 
-static MSIHANDLE package_from_db(MSIHANDLE hdb)
+static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle)
 {
     UINT res;
-    CHAR szPackage[10];
+    CHAR szPackage[12];
     MSIHANDLE hPackage;
 
-    sprintf(szPackage,"#%i",hdb);
-    res = MsiOpenPackage(szPackage,&hPackage);
+    sprintf(szPackage, "#%u", hdb);
+    res = MsiOpenPackage(szPackage, &hPackage);
     if (res != ERROR_SUCCESS)
-        return 0;
+    {
+        MsiCloseHandle(hdb);
+        return res;
+    }
 
     res = MsiCloseHandle(hdb);
     if (res != ERROR_SUCCESS)
-        return 0;
+    {
+        MsiCloseHandle(hPackage);
+        return res;
+    }
 
-    return hPackage;
+    *handle = hPackage;
+    return ERROR_SUCCESS;
 }
 
 static void create_test_file(const CHAR *name)
@@ -809,8 +892,14 @@ static void test_createpackage(void)
     MSIHANDLE hPackage = 0;
     UINT res;
 
-    hPackage = package_from_db(create_package_db());
-    ok( hPackage != 0, " Failed to create package\n");
+    res = package_from_db(create_package_db(), &hPackage);
+    if (res == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( res == ERROR_SUCCESS, " Failed to create package %u\n", res );
 
     res = MsiCloseHandle( hPackage);
     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
@@ -825,8 +914,14 @@ static void test_doaction( void )
     r = MsiDoAction( -1, NULL );
     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
 
-    hpkg = package_from_db(create_package_db());
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db(create_package_db(), &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     r = MsiDoAction(hpkg, NULL);
     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
@@ -851,8 +946,14 @@ static void test_gettargetpath_bad(void)
     DWORD sz;
     UINT r;
 
-    hpkg = package_from_db(create_package_db());
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db(create_package_db(), &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     r = MsiGetTargetPath( 0, NULL, NULL, NULL );
     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
@@ -971,8 +1072,16 @@ static void test_settargetpath(void)
     r = add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" );
     ok( r == S_OK, "cannot add file to the File table: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db( hdb, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
@@ -1025,6 +1134,7 @@ static void test_settargetpath(void)
     r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
     ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
 
+    buffer[0] = 0;
     sz = sizeof buffer - 1;
     lstrcat( tempdir, "\\" );
     r = MsiGetTargetPath( hpkg, "TARGETDIR", buffer, &sz );
@@ -1035,13 +1145,29 @@ static void test_settargetpath(void)
     query_file_path( hpkg, "[#RootFile]", buffer );
     ok( !lstrcmp(buffer, file), "Expected %s, got %s\n", file, buffer);
 
+    buffer[0] = 0;
+    sz = sizeof(buffer);
+    r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
+    ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
+    lstrcatA( tempdir, "TestParent\\" );
+    ok( !lstrcmpi(buffer, tempdir), "Expected \"%s\", got \"%s\"\n", tempdir, buffer );
+
     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two" );
     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
 
+    buffer[0] = 0;
+    sz = sizeof(buffer);
+    r = MsiGetPropertyA( hpkg, "TestParent", buffer, &sz );
+    ok( r == ERROR_SUCCESS, "MsiGetProperty returned %u\n", r );
+    ok( lstrcmpi(buffer, "C:\\one\\two\\TestDir\\"),
+        "Expected \"C:\\one\\two\\TestDir\\\", got \"%s\"\n", buffer );
+
+    buffer[0] = 0;
     query_file_path( hpkg, "[#TestFile]", buffer );
     ok( !lstrcmpi(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
         "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
 
+    buffer[0] = 0;
     sz = sizeof buffer - 1;
     r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
@@ -1050,21 +1176,50 @@ static void test_settargetpath(void)
     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two\\three" );
     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
 
+    buffer[0] = 0;
     sz = sizeof buffer - 1;
     r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
     ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
     ok( !lstrcmpi(buffer, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", buffer);
 
+    r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\one\\\\two  " );
+    ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
+
+    buffer[0] = 0;
+    sz = sizeof buffer - 1;
+    r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
+    ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
+    ok( !lstrcmpi(buffer, "C:\\one\\two\\"), "Expected \"C:\\one\\two\\\", got %s\n", buffer);
+
+    r = MsiSetTargetPath( hpkg, "TestParent", "C:\\\\ Program Files \\\\ " );
+    ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
+
+    buffer[0] = 0;
+    sz = sizeof buffer - 1;
+    r = MsiGetTargetPath( hpkg, "TestParent", buffer, &sz );
+    ok( r == ERROR_SUCCESS, "failed to get target path: %d\n", r);
+    ok( !lstrcmpi(buffer, "C:\\Program Files\\"), "Expected \"C:\\Program Files\\\", got %s\n", buffer);
+
     MsiCloseHandle( hpkg );
 }
 
 static void test_condition(void)
 {
+    static const WCHAR cond1[] = {'\"','a',0x30a,'\"','<','\"',0xe5,'\"',0};
+    static const WCHAR cond2[] = {'\"','a',0x30a,'\"','>','\"',0xe5,'\"',0};
+    static const WCHAR cond3[] = {'\"','a',0x30a,'\"','<','>','\"',0xe5,'\"',0};
+    static const WCHAR cond4[] = {'\"','a',0x30a,'\"','=','\"',0xe5,'\"',0};
     MSICONDITION r;
     MSIHANDLE hpkg;
 
-    hpkg = package_from_db(create_package_db());
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db(create_package_db(), &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     r = MsiEvaluateCondition(0, NULL);
     ok( r == MSICONDITION_ERROR, "wrong return val\n");
@@ -1773,6 +1928,22 @@ static void test_condition(void)
     r = MsiEvaluateCondition(hpkg, "A <= X");
     ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r);
 
+    r = MsiEvaluateConditionW(hpkg, cond1);
+    ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
+        "wrong return val (%d)\n", r);
+
+    r = MsiEvaluateConditionW(hpkg, cond2);
+    ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
+        "wrong return val (%d)\n", r);
+
+    r = MsiEvaluateConditionW(hpkg, cond3);
+    ok( r == MSICONDITION_TRUE || broken(r == MSICONDITION_FALSE),
+        "wrong return val (%d)\n", r);
+
+    r = MsiEvaluateConditionW(hpkg, cond4);
+    ok( r == MSICONDITION_FALSE || broken(r == MSICONDITION_TRUE),
+        "wrong return val (%d)\n", r);
+
     MsiCloseHandle( hpkg );
     DeleteFile(msifile);
 }
@@ -1810,8 +1981,14 @@ static void test_props(void)
             "VALUES( 'MetadataCompName', 'Photoshop.dll' )");
     ok( r == ERROR_SUCCESS , "Failed\n" );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db( hdb, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     /* test invalid values */
     r = MsiGetProperty( 0, NULL, NULL, NULL );
@@ -2007,15 +2184,21 @@ static void test_property_table(void)
     const char *query;
     UINT r;
     MSIHANDLE hpkg, hdb, hrec;
-    char buffer[MAX_PATH];
+    char buffer[MAX_PATH], package[10];
     DWORD sz;
     BOOL found;
 
     hdb = create_package_db();
     ok( hdb, "failed to create package\n");
 
-    hpkg = package_from_db(hdb);
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     MsiCloseHandle(hdb);
 
@@ -2050,15 +2233,14 @@ static void test_property_table(void)
     r = run_query(hdb, query);
     ok(r == ERROR_SUCCESS, "failed to add column\n");
 
-    hpkg = package_from_db(hdb);
-    todo_wine
-    {
-        ok(!hpkg, "package should not be created\n");
-    }
+    sprintf(package, "#%i", hdb);
+    r = MsiOpenPackage(package, &hpkg);
+    todo_wine ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
+    if (r == ERROR_SUCCESS)
+        MsiCloseHandle(hpkg);
 
-    MsiCloseHandle(hdb);
-    MsiCloseHandle(hpkg);
-    DeleteFile(msifile);
+    r = MsiCloseHandle(hdb);
+    ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
 
     hdb = create_package_db();
     ok (hdb, "failed to create package database\n");
@@ -2069,8 +2251,8 @@ static void test_property_table(void)
     r = add_property_entry(hdb, "'prop', 'val'");
     ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     MsiCloseHandle(hdb);
 
@@ -2191,6 +2373,11 @@ static void test_msipackage(void)
 
     /* empty szPackagePath */
     r = MsiOpenPackage("", &hpack);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     todo_wine
     {
         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -2275,8 +2462,14 @@ static void test_formatrecord2(void)
     DWORD sz;
     UINT r;
 
-    hpkg = package_from_db(create_package_db());
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db(create_package_db(), &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     r = MsiSetProperty(hpkg, "Manufacturer", " " );
     ok( r == ERROR_SUCCESS, "set property failed\n");
@@ -2290,9 +2483,12 @@ static void test_formatrecord2(void)
     buffer[0] = 0;
     sz = sizeof buffer;
     r = MsiFormatRecord( hpkg, hrec, buffer, &sz );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
 
     r = MsiRecordSetString(hrec, 0, "[foo][1]");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     r = MsiRecordSetString(hrec, 1, "hoo");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     sz = sizeof buffer;
     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
     ok( sz == 3, "size wrong\n");
@@ -2300,6 +2496,7 @@ static void test_formatrecord2(void)
     ok( r == ERROR_SUCCESS, "format failed\n");
 
     r = MsiRecordSetString(hrec, 0, "x[~]x");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     sz = sizeof buffer;
     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
     ok( sz == 3, "size wrong\n");
@@ -2307,7 +2504,9 @@ static void test_formatrecord2(void)
     ok( r == ERROR_SUCCESS, "format failed\n");
 
     r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     r = MsiRecordSetString(hrec, 1, "hoo");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     sz = sizeof buffer;
     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
     ok( sz == 3, "size wrong\n");
@@ -2315,6 +2514,7 @@ static void test_formatrecord2(void)
     ok( r == ERROR_SUCCESS, "format failed\n");
 
     r = MsiRecordSetString(hrec, 0, "[\\[]");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     sz = sizeof buffer;
     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
     ok( sz == 1, "size wrong\n");
@@ -2323,6 +2523,7 @@ static void test_formatrecord2(void)
 
     SetEnvironmentVariable("FOO", "BAR");
     r = MsiRecordSetString(hrec, 0, "[%FOO]");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     sz = sizeof buffer;
     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
     ok( sz == 3, "size wrong\n");
@@ -2330,7 +2531,9 @@ static void test_formatrecord2(void)
     ok( r == ERROR_SUCCESS, "format failed\n");
 
     r = MsiRecordSetString(hrec, 0, "[[1]]");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     r = MsiRecordSetString(hrec, 1, "%FOO");
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     sz = sizeof buffer;
     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
     ok( sz == 3, "size wrong\n");
@@ -2342,16 +2545,84 @@ static void test_formatrecord2(void)
     DeleteFile(msifile);
 }
 
+static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error,
+                                 INSTALLSTATE expected_state, INSTALLSTATE expected_action, int todo )
+{
+    UINT r;
+    INSTALLSTATE state = 0xdeadbee;
+    INSTALLSTATE action = 0xdeadbee;
+
+    r = MsiGetFeatureState( package, feature, &state, &action );
+    ok( r == error, "%u: expected %d got %d\n", line, error, r );
+    if (r == ERROR_SUCCESS)
+    {
+        ok( state == expected_state, "%u: expected state %d got %d\n",
+            line, expected_state, state );
+        if (todo) todo_wine
+            ok( action == expected_action, "%u: expected action %d got %d\n",
+                line, expected_action, action );
+        else
+            ok( action == expected_action, "%u: expected action %d got %d\n",
+                line, expected_action, action );
+    }
+    else
+    {
+        ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state );
+        if (todo) todo_wine
+            ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
+        else
+            ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action );
+
+    }
+}
+
+static void test_component_states( UINT line, MSIHANDLE package, const char *component, UINT error,
+                                   INSTALLSTATE expected_state, INSTALLSTATE expected_action, int todo )
+{
+    UINT r;
+    INSTALLSTATE state = 0xdeadbee;
+    INSTALLSTATE action = 0xdeadbee;
+
+    r = MsiGetComponentState( package, component, &state, &action );
+    ok( r == error, "%u: expected %d got %d\n", line, error, r );
+    if (r == ERROR_SUCCESS)
+    {
+        ok( state == expected_state, "%u: expected state %d got %d\n",
+            line, expected_state, state );
+        if (todo) todo_wine
+            ok( action == expected_action, "%u: expected action %d got %d\n",
+                line, expected_action, action );
+        else
+            ok( action == expected_action, "%u: expected action %d got %d\n",
+                line, expected_action, action );
+    }
+    else
+    {
+        ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n",
+            line, state );
+        if (todo) todo_wine
+            ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
+                line, action );
+        else
+            ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n",
+                line, action );
+    }
+}
+
 static void test_states(void)
 {
+    static char msifile2[] = "winetest2-package.msi";
+    static char msifile3[] = "winetest3-package.msi";
+    static char msifile4[] = "winetest4-package.msi";
     MSIHANDLE hpkg;
     UINT r;
     MSIHANDLE hdb;
-    INSTALLSTATE state, action;
 
-    static const CHAR msifile2[] = "winetest2-package.msi";
-    static const CHAR msifile3[] = "winetest3-package.msi";
-    static const CHAR msifile4[] = "winetest4-package.msi";
+    if (is_process_limited())
+    {
+        skip("process is limited\n");
+        return;
+    }
 
     hdb = create_package_db();
     ok ( hdb, "failed to create package database\n" );
@@ -2362,7 +2633,7 @@ static void test_states(void)
     r = create_property_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create Property table: %d\n", r );
 
-    r = add_property_entry( hdb, "'ProductCode', '{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}'" );
+    r = add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" );
     ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
 
     r = add_property_entry( hdb, "'ProductLanguage', '1033'" );
@@ -2374,6 +2645,9 @@ static void test_states(void)
     r = add_property_entry( hdb, "'ProductVersion', '1.1.1'" );
     ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
 
+    r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
+    ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r );
+
     r = create_install_execute_sequence_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table: %d\n", r );
 
@@ -2543,6 +2817,13 @@ static void test_states(void)
     r = add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" );
     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
 
+    /* msidbFeatureAttributesUIDisallowAbsent */
+    r = add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" );
+    ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
+
+    r = add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" );
+    ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
+
     r = create_feature_components_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
 
@@ -2612,6 +2893,9 @@ static void test_states(void)
     r = add_feature_components_entry( hdb, "'ten', 'chi'" );
     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
 
+    r = add_feature_components_entry( hdb, "'eleven', 'psi'" );
+    ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
+
     r = create_file_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
 
@@ -2679,6 +2963,9 @@ static void test_states(void)
     r = add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" );
     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
 
+    r = add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" );
+    ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
+
     MsiDatabaseCommit(hdb);
 
     /* these properties must not be in the saved msi file */
@@ -2697,8 +2984,14 @@ static void test_states(void)
     r = add_property_entry( hdb, "'REINSTALLMODE', 'omus'");
     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db( hdb, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
     MsiCloseHandle(hdb);
 
@@ -2706,885 +2999,65 @@ static void test_states(void)
     CopyFileA(msifile, msifile3, FALSE);
     CopyFileA(msifile, msifile4, FALSE);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
 
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
     r = MsiDoAction( hpkg, "FileCost");
     ok( r == ERROR_SUCCESS, "file cost failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "CostFinalize");
     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
 
     MsiCloseHandle( hpkg );
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     /* publish the features and components */
     r = MsiInstallProduct(msifile, "ADDLOCAL=one,four ADDSOURCE=two,three REMOVE=six,seven REINSTALL=eight,nine,ten");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -3605,880 +3078,63 @@ static void test_states(void)
     r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'");
     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db( hdb, &hpkg );
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
     MsiCloseHandle(hdb);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
 
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "FileCost");
     ok( r == ERROR_SUCCESS, "file cost failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "CostFinalize");
     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
 
     MsiCloseHandle(hpkg);
 
@@ -4497,885 +3153,55 @@ static void test_states(void)
     r = add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten'");
     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
+    r = package_from_db( hdb, &hpkg );
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
+
+    test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
 
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    r = MsiDoAction( hpkg, "FileCost");
-    ok( r == ERROR_SUCCESS, "file cost failed\n");
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "CostFinalize");
     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    todo_wine ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    todo_wine ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    todo_wine ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 1 );
+    test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 1 );
+    test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 1 );
+    test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
+
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
+    test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
+    test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
+    test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
 
     MsiCloseHandle(hpkg);
 
@@ -5394,885 +3220,61 @@ static void test_states(void)
     r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
+    r = package_from_db( hdb, &hpkg );
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
+
+    test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
 
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "FileCost");
     ok( r == ERROR_SUCCESS, "file cost failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "CostFinalize");
     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
+
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
 
     MsiCloseHandle(hpkg);
 
@@ -6287,885 +3289,61 @@ static void test_states(void)
     r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'");
     ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
-    ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
-    ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
+    r = package_from_db( hdb, &hpkg );
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
+
+    test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_UNKNOWN_COMPONENT, 0, 0, 0 );
 
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "FileCost");
     ok( r == ERROR_SUCCESS, "file cost failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiDoAction( hpkg, "CostFinalize");
     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "two", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "three", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "four", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "five", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "six", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "seven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "eight", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "nine", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "ten", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "alpha", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "beta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "gamma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "theta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "zeta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "iota", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "eta", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "kappa", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lambda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "mu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "nu", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "xi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "omicron", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "pi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "rho", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "sigma", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    ok( state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "tau", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "phi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "chi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    ok( state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
+    test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "three", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "four", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "five", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "six", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "seven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "eight", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "nine", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "ten", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "eleven", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 1 );
+
+    test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, 0 );
 
     MsiCloseHandle(hpkg);
 
@@ -7187,8 +3365,14 @@ static void test_getproperty(void)
     DWORD size;
     UINT r;
 
-    hPackage = package_from_db(create_package_db());
-    ok( hPackage != 0, " Failed to create package\n");
+    r = package_from_db(create_package_db(), &hPackage);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "Failed to create package %u\n", r );
 
     /* set the property */
     r = MsiSetProperty(hPackage, "Name", "Value");
@@ -7229,6 +3413,7 @@ static void test_removefiles(void)
     MSIHANDLE hpkg;
     UINT r;
     MSIHANDLE hdb;
+    INSTALLSTATE installed, action;
 
     hdb = create_package_db();
     ok ( hdb, "failed to create package database\n" );
@@ -7263,6 +3448,9 @@ static void test_removefiles(void)
     r = add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
 
+    r = add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" );
+    ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
+
     r = create_feature_components_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
 
@@ -7284,6 +3472,9 @@ static void test_removefiles(void)
     r = add_feature_components_entry( hdb, "'one', 'carbon'" );
     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
 
+    r = add_feature_components_entry( hdb, "'one', 'oxygen'" );
+    ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
+
     r = create_file_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
 
@@ -7305,11 +3496,20 @@ static void test_removefiles(void)
     r = add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
 
+    r = add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" );
+    ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
+
     r = create_remove_file_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create Remove File table: %d\n", r);
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db( hdb, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
     MsiCloseHandle( hdb );
 
@@ -7319,25 +3519,43 @@ static void test_removefiles(void)
     create_test_file( "beryllium.txt" );
     create_test_file( "boron.txt" );
     create_test_file( "carbon.txt" );
+    create_test_file( "oxygen.txt" );
 
     r = MsiSetProperty( hpkg, "TARGETDIR", CURR_DIR );
     ok( r == ERROR_SUCCESS, "set property failed\n");
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+    r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
+    ok( r == ERROR_UNKNOWN_COMPONENT, "expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
+
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
 
     r = MsiDoAction( hpkg, "FileCost");
-    ok( r == ERROR_SUCCESS, "cost finalize failed\n");
+    ok( r == ERROR_SUCCESS, "file cost failed\n");
+
+    installed = action = 0xdeadbeef;
+    r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
+    ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
+    ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
+    ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
 
     r = MsiDoAction( hpkg, "CostFinalize");
     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
 
     r = MsiDoAction( hpkg, "InstallValidate");
-    ok( r == ERROR_SUCCESS, "cost finalize failed\n");
+    ok( r == ERROR_SUCCESS, "install validate failed\n");
 
     r = MsiSetComponentState( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
 
+    installed = action = 0xdeadbeef;
+    r = MsiGetComponentState( hpkg, "hydrogen", &installed, &action );
+    ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
+    ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
+    todo_wine ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
+
     r = MsiSetComponentState( hpkg, "helium", INSTALLSTATE_LOCAL );
     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
 
@@ -7353,15 +3571,37 @@ static void test_removefiles(void)
     r = MsiSetComponentState( hpkg, "carbon", INSTALLSTATE_SOURCE );
     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
 
+    installed = action = 0xdeadbeef;
+    r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
+    ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
+    ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
+    ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
+
+    r = MsiSetComponentState( hpkg, "oxygen", INSTALLSTATE_ABSENT );
+    ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
+
+    installed = action = 0xdeadbeef;
+    r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
+    ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
+    ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
+    ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
+
     r = MsiDoAction( hpkg, "RemoveFiles");
     ok( r == ERROR_SUCCESS, "remove files failed\n");
 
+    installed = action = 0xdeadbeef;
+    r = MsiGetComponentState( hpkg, "oxygen", &installed, &action );
+    ok( r == ERROR_SUCCESS, "failed to get component state %u\n", r );
+    ok( installed == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", installed );
+    ok( action == INSTALLSTATE_UNKNOWN, "expected INSTALLSTATE_UNKNOWN, got %d\n", action );
+
     ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
     ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");    
     ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
     ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
     ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
     ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
+    ok(DeleteFileA("oxygen.txt"), "Expected oxygen.txt to exist\n");
 
     MsiCloseHandle( hpkg );
     DeleteFileA(msifile);
@@ -7373,7 +3613,7 @@ static void test_appsearch(void)
     UINT r;
     MSIHANDLE hdb;
     CHAR prop[MAX_PATH];
-    DWORD size = MAX_PATH;
+    DWORD size;
 
     hdb = create_package_db();
     ok ( hdb, "failed to create package database\n" );
@@ -7384,33 +3624,57 @@ static void test_appsearch(void)
     r = add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
     ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
 
+    r = add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" );
+    ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
+
     r = create_reglocator_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
 
-    r = add_reglocator_entry( hdb, "'NewSignature1', 0, 'htmlfile\\shell\\open\\command', '', 1" );
+    r = add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 );
+    ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
+
+    r = create_drlocator_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create DrLocator table: %d\n", r );
+
+    r = add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" );
     ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
 
     r = create_signature_table( hdb );
     ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r );
 
     r = add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
-    ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r );
+    ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" );
+    ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r );
 
+    r = package_from_db( hdb, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
     MsiCloseHandle( hdb );
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
     r = MsiDoAction( hpkg, "AppSearch" );
     ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
 
+    size = sizeof(prop);
     r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
-    todo_wine
-    {
-        ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
-    }
+    ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
+
+    size = sizeof(prop);
+    r = MsiGetPropertyA( hpkg, "NOTEPAD", prop, &size );
+    ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
 
+done:
     MsiCloseHandle( hpkg );
     DeleteFileA(msifile);
 }
@@ -7424,8 +3688,14 @@ static void test_appsearch_complocator(void)
     DWORD size;
     UINT r;
 
-    if (!get_user_sid(&usersid))
+    if (!(usersid = get_user_sid()))
+        return;
+
+    if (is_process_limited())
+    {
+        skip("process is limited\n");
         return;
+    }
 
     create_test_file("FileName1");
     create_test_file("FileName4");
@@ -7588,12 +3858,19 @@ static void test_appsearch_complocator(void)
     r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "Expected a valid package handle\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
+    ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
 
     r = MsiSetPropertyA(hpkg, "SIGPROP8", "october");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     r = MsiDoAction(hpkg, "AppSearch");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
@@ -7687,6 +3964,9 @@ static void test_appsearch_complocator(void)
     delete_component_path("{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}",
                           MSIINSTALLCONTEXT_MACHINE, NULL);
 
+    MsiCloseHandle(hpkg);
+
+error:
     DeleteFileA("FileName1");
     DeleteFileA("FileName2");
     DeleteFileA("FileName3");
@@ -7697,7 +3977,6 @@ static void test_appsearch_complocator(void)
     DeleteFileA("FileName8.dll");
     DeleteFileA("FileName9.dll");
     DeleteFileA("FileName10.dll");
-    MsiCloseHandle(hpkg);
     DeleteFileA(msifile);
     LocalFree(usersid);
 }
@@ -7705,19 +3984,15 @@ static void test_appsearch_complocator(void)
 static void test_appsearch_reglocator(void)
 {
     MSIHANDLE hpkg, hdb;
-    CHAR path[MAX_PATH];
-    CHAR prop[MAX_PATH];
-    DWORD binary[2];
-    DWORD size, val;
-    BOOL space, version;
-    HKEY hklm, classes;
-    HKEY hkcu, users;
-    LPSTR pathdata;
-    LPSTR pathvar;
+    CHAR path[MAX_PATH], prop[MAX_PATH];
+    DWORD binary[2], size, val;
+    BOOL space, version, is_64bit = sizeof(void *) > sizeof(int);
+    HKEY hklm, classes, hkcu, users;
+    LPSTR pathdata, pathvar, ptr;
     LPCSTR str;
-    LPSTR ptr;
     LONG res;
-    UINT r;
+    UINT r, type = 0;
+    SYSTEM_INFO si;
 
     version = TRUE;
     if (!create_file_with_version("test.dll", MAKELONG(2, 1), MAKELONG(4, 3)))
@@ -7726,6 +4001,11 @@ static void test_appsearch_reglocator(void)
     DeleteFileA("test.dll");
 
     res = RegCreateKeyA(HKEY_CLASSES_ROOT, "Software\\Wine", &classes);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     res = RegSetValueExA(classes, "Value1", 0, REG_SZ,
@@ -7835,11 +4115,13 @@ static void test_appsearch_reglocator(void)
     sprintf(path, "\"%s\\FileName1\" -option", CURR_DIR);
     res = RegSetValueExA(hklm, "value16", 0, REG_SZ,
                          (const BYTE *)path, lstrlenA(path) + 1);
+    ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
 
     space = (strchr(CURR_DIR, ' ')) ? TRUE : FALSE;
     sprintf(path, "%s\\FileName1 -option", CURR_DIR);
     res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
                          (const BYTE *)path, lstrlenA(path) + 1);
+    ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
 
     hdb = create_package_db();
     ok(hdb, "Expected a valid database handle\n");
@@ -7940,154 +4222,152 @@ static void test_appsearch_reglocator(void)
     r = create_reglocator_table(hdb);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    type = msidbLocatorTypeRawValue;
+    if (is_64bit)
+        type |= msidbLocatorType64bit;
+
     /* HKLM, msidbLocatorTypeRawValue, REG_SZ */
-    str = "'NewSignature1', 2, 'Software\\Wine', 'Value1', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, positive DWORD */
-    str = "'NewSignature2', 2, 'Software\\Wine', 'Value2', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, negative DWORD */
-    str = "'NewSignature3', 2, 'Software\\Wine', 'Value3', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
-    str = "'NewSignature4', 2, 'Software\\Wine', 'Value4', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */
-    str = "'NewSignature5', 2, 'Software\\Wine', 'Value5', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */
-    str = "'NewSignature6', 2, 'Software\\Wine', 'Value6', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */
-    str = "'NewSignature7', 2, 'Software\\Wine', 'Value7', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */
-    str = "'NewSignature8', 2, 'Software\\Wine', 'Value8', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    type = msidbLocatorTypeFileName;
+    if (is_64bit)
+        type |= msidbLocatorType64bit;
+
     /* HKLM, msidbLocatorTypeFileName, signature, file exists */
-    str = "'NewSignature9', 2, 'Software\\Wine', 'Value9', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */
-    str = "'NewSignature10', 2, 'Software\\Wine', 'Value10', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeFileName, no signature */
-    str = "'NewSignature11', 2, 'Software\\Wine', 'Value9', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    type = msidbLocatorTypeDirectory;
+    if (is_64bit)
+        type |= msidbLocatorType64bit;
+
     /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */
-    str = "'NewSignature12', 2, 'Software\\Wine', 'Value9', 0";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */
-    str = "'NewSignature13', 2, 'Software\\Wine', 'Value11', 0";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeDirectory, signature, file exists */
-    str = "'NewSignature14', 2, 'Software\\Wine', 'Value9', 0";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    type = msidbLocatorTypeRawValue;
+    if (is_64bit)
+        type |= msidbLocatorType64bit;
+
     /* HKCR, msidbLocatorTypeRawValue, REG_SZ */
-    str = "'NewSignature15', 0, 'Software\\Wine', 'Value1', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKCU, msidbLocatorTypeRawValue, REG_SZ */
-    str = "'NewSignature16', 1, 'Software\\Wine', 'Value1', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKU, msidbLocatorTypeRawValue, REG_SZ */
-    str = "'NewSignature17', 3, 'S-1-5-18\\Software\\Wine', 'Value1', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */
-    str = "'NewSignature18', 2, 'Software\\Wine', '', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */
-    str = "'NewSignature19', 2, 'Software\\IDontExist', '', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */
-    str = "'NewSignature20', 2, 'Software\\Wine', 'Value12', 2";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    type = msidbLocatorTypeFileName;
+    if (is_64bit)
+        type |= msidbLocatorType64bit;
+
     /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */
-    str = "'NewSignature21', 2, 'Software\\Wine', 'Value13', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */
-    str = "'NewSignature22', 2, 'Software\\Wine', 'Value14', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */
-    str = "'NewSignature23', 2, 'Software\\Wine', 'Value15', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */
-    str = "'NewSignature24', 2, 'Software\\Wine', 'Value11', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */
-    str = "'NewSignature25', 2, 'Software\\Wine', 'Value10', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    type = msidbLocatorTypeDirectory;
+    if (is_64bit)
+        type |= msidbLocatorType64bit;
+
     /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */
-    str = "'NewSignature26', 2, 'Software\\Wine', 'Value11', 0";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */
-    str = "'NewSignature27', 2, 'Software\\Wine', 'Value10', 0";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */
-    str = "'NewSignature28', 2, 'Software\\Wine', 'Value10', 0";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    type = msidbLocatorTypeFileName;
+    if (is_64bit)
+        type |= msidbLocatorType64bit;
+
     /* HKLM, msidbLocatorTypeFile, file exists, in quotes */
-    str = "'NewSignature29', 2, 'Software\\Wine', 'Value16', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* HKLM, msidbLocatorTypeFile, file exists, no quotes */
-    str = "'NewSignature30', 2, 'Software\\Wine', 'Value17', 1";
-    r = add_reglocator_entry(hdb, str);
+    r = add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     r = create_signature_table(hdb);
@@ -8134,8 +4414,10 @@ static void test_appsearch_reglocator(void)
     r = add_signature_entry(hdb, str);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "Expected a valid package handle\n");
+    r = package_from_db(hdb, &hpkg);
+    ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
     r = MsiDoAction(hpkg, "AppSearch");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -8156,28 +4438,28 @@ static void test_appsearch_reglocator(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop);
 
-    size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
-    if (size == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
+    memset(&si, 0, sizeof(si));
+    if (pGetNativeSystemInfo) pGetNativeSystemInfo(&si);
+
+    if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
     {
-        /* Workaround for Win95 */
-        CHAR tempbuf[1];
-        size = ExpandEnvironmentStringsA("%PATH%", tempbuf, 0);
-    }
-    pathvar = HeapAlloc(GetProcessHeap(), 0, size);
-    ExpandEnvironmentStringsA("%PATH%", pathvar, size);
+        size = ExpandEnvironmentStringsA("%PATH%", NULL, 0);
+        pathvar = HeapAlloc(GetProcessHeap(), 0, size);
+        ExpandEnvironmentStringsA("%PATH%", pathvar, size);
 
-    size = 0;
-    r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
-    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+        size = 0;
+        r = MsiGetPropertyA(hpkg, "SIGPROP4", NULL, &size);
+        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    pathdata = HeapAlloc(GetProcessHeap(), 0, ++size);
-    r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
-    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    ok(!lstrcmpA(pathdata, pathvar),
-       "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
+        pathdata = HeapAlloc(GetProcessHeap(), 0, ++size);
+        r = MsiGetPropertyA(hpkg, "SIGPROP4", pathdata, &size);
+        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+        ok(!lstrcmpA(pathdata, pathvar),
+            "Expected \"%s\", got \"%s\"\n", pathvar, pathdata);
 
-    HeapFree(GetProcessHeap(), 0, pathvar);
-    HeapFree(GetProcessHeap(), 0, pathdata);
+        HeapFree(GetProcessHeap(), 0, pathvar);
+        HeapFree(GetProcessHeap(), 0, pathdata);
+    }
 
     size = MAX_PATH;
     r = MsiGetPropertyA(hpkg, "SIGPROP5", prop, &size);
@@ -8358,7 +4640,7 @@ static void test_appsearch_reglocator(void)
     RegDeleteValueA(hklm, "Value15");
     RegDeleteValueA(hklm, "Value16");
     RegDeleteValueA(hklm, "Value17");
-    RegDeleteKeyA(hklm, "");
+    RegDeleteKey(hklm, "");
     RegCloseKey(hklm);
 
     RegDeleteValueA(classes, "Value1");
@@ -8555,8 +4837,15 @@ static void test_appsearch_inilocator(void)
     r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "Expected a valid package handle\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
+    ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
     r = MsiDoAction(hpkg, "AppSearch");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -8633,12 +4922,14 @@ static void test_appsearch_inilocator(void)
         ok(!lstrcmpA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
     }
 
+    MsiCloseHandle(hpkg);
+
+error:
     delete_win_ini("IniFile.ini");
     DeleteFileA("FileName1");
     DeleteFileA("FileName2.dll");
     DeleteFileA("FileName3.dll");
     DeleteFileA("FileName4.dll");
-    MsiCloseHandle(hpkg);
     DeleteFileA(msifile);
 }
 
@@ -8743,6 +5034,9 @@ static void test_appsearch_drlocator(void)
     r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
+    r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
     r = create_drlocator_table(hdb);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
@@ -8801,7 +5095,19 @@ static void test_appsearch_drlocator(void)
     r = add_drlocator_entry(hdb, path);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    r = create_signature_table(hdb);
+    r = create_reglocator_table(hdb);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+    /* parent */
+    r = add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+    /* parent is in RegLocator, no path, depth 0, no signature */
+    sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
+    r = add_drlocator_entry(hdb, path);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+    r = create_signature_table(hdb);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     str = "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''";
@@ -8836,8 +5142,15 @@ static void test_appsearch_drlocator(void)
     r = add_signature_entry(hdb, str);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "Expected a valid package handle\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
+    ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r);
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
     r = MsiDoAction(hpkg, "AppSearch");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -8907,6 +5220,15 @@ static void test_appsearch_drlocator(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
 
+    size = MAX_PATH;
+    strcpy(path, "c:\\");
+    r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
+
+    MsiCloseHandle(hpkg);
+
+error:
     DeleteFileA("FileName1");
     DeleteFileA("FileName3.dll");
     DeleteFileA("FileName4.dll");
@@ -8916,7 +5238,6 @@ static void test_appsearch_drlocator(void)
     RemoveDirectoryA("one\\two");
     RemoveDirectoryA("one");
     RemoveDirectoryA("another");
-    MsiCloseHandle(hpkg);
     DeleteFileA(msifile);
 }
 
@@ -8925,7 +5246,6 @@ static void test_featureparents(void)
     MSIHANDLE hpkg;
     UINT r;
     MSIHANDLE hdb;
-    INSTALLSTATE state, action;
 
     hdb = create_package_db();
     ok ( hdb, "failed to create package database\n" );
@@ -8957,6 +5277,10 @@ static void test_featureparents(void)
     r = add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
 
+    /* msidbFeatureAttributesUIDisallowAbsent */
+    r = add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" );
+    ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
+
     /* disabled because of install level */
     r = add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
@@ -9007,6 +5331,7 @@ static void test_featureparents(void)
 
     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
     r = add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
 
     r = add_feature_components_entry( hdb, "'zodiac', 'leo'" );
     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
@@ -9092,11 +5417,19 @@ static void test_featureparents(void)
     r = add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" );
     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db( hdb, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
     MsiCloseHandle( hdb );
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     r = MsiDoAction( hpkg, "CostInitialize");
     ok( r == ERROR_SUCCESS, "cost init failed\n");
 
@@ -9106,219 +5439,53 @@ static void test_featureparents(void)
     r = MsiDoAction( hpkg, "CostFinalize");
     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "zodiac", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "perseus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "orion", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "waters", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "bayer", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "leo", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "virgo", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected virgo INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected virgo INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "libra", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected libra INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected libra INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "cassiopeia", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected cassiopeia INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected cassiopeia INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "cepheus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected cepheus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected cepheus INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "andromeda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected andromeda INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected andromeda INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "canis", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected canis INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected canis INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "monoceros", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected monoceros INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected monoceros INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lepus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected lepus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected lepus INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delphinus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected delphinus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected delphinus INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "hydrus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected hydrus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected hydrus INSTALLSTATE_UNKNOWN, got %d\n", action);
+    test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+
+    test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
 
     r = MsiSetFeatureState(hpkg, "orion", INSTALLSTATE_ABSENT);
     ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
 
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "zodiac", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected zodiac INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected zodiac INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "perseus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected perseus INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected perseus INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "orion", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected orion INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_ABSENT, "Expected orion INSTALLSTATE_ABSENT, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "leo", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected leo INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected leo INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "virgo", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected virgo INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected virgo INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "libra", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected libra INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected libra INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "cassiopeia", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected cassiopeia INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_LOCAL, "Expected cassiopeia INSTALLSTATE_LOCAL, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "cepheus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected cepheus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected cepheus INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "andromeda", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected andromeda INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_SOURCE, "Expected andromeda INSTALLSTATE_SOURCE, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "canis", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected canis INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected canis INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "monoceros", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected monoceros INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected monoceros INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "lepus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected lepus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected lepus INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "delphinus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected delphinus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected delphinus INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "hydrus", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected hydrus INSTALLSTATE_UNKNOWN, got %d\n", state);
-    ok( action == INSTALLSTATE_UNKNOWN, "Expected hydrus INSTALLSTATE_UNKNOWN, got %d\n", action);
-    
+    r = MsiSetFeatureState(hpkg, "lyra", INSTALLSTATE_ABSENT);
+    ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
+
+    r = MsiSetFeatureState(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
+    ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
+
+    test_feature_states( __LINE__, hpkg, "zodiac", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_LOCAL, 0 );
+    test_feature_states( __LINE__, hpkg, "perseus", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_SOURCE, 0 );
+    test_feature_states( __LINE__, hpkg, "orion", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, 0 );
+    test_feature_states( __LINE__, hpkg, "lyra", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_ABSENT, 0 );
+    test_feature_states( __LINE__, hpkg, "waters", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+    test_feature_states( __LINE__, hpkg, "bayer", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, 0 );
+
+    test_component_states( __LINE__, hpkg, "leo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "virgo", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "libra", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "cassiopeia", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_LOCAL, 0 );
+    test_component_states( __LINE__, hpkg, "cepheus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "andromeda", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_SOURCE, 0 );
+    test_component_states( __LINE__, hpkg, "canis", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "monoceros", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "lepus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "delphinus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+    test_component_states( __LINE__, hpkg, "hydrus", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, 0 );
+
     MsiCloseHandle(hpkg);
     DeleteFileA(msifile);
 }
@@ -9326,34 +5493,62 @@ static void test_featureparents(void)
 static void test_installprops(void)
 {
     MSIHANDLE hpkg, hdb;
-    CHAR path[MAX_PATH];
-    CHAR buf[MAX_PATH];
+    CHAR path[MAX_PATH], buf[MAX_PATH];
     DWORD size, type;
     LANGID langid;
     HKEY hkey1, hkey2;
     int res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
+    SYSTEM_INFO si;
+    INSTALLUILEVEL uilevel;
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     GetCurrentDirectory(MAX_PATH, path);
     lstrcat(path, "\\");
     lstrcat(path, msifile);
 
+    uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
+
     hdb = create_package_db();
     ok( hdb, "failed to create database\n");
 
-    hpkg = package_from_db(hdb);
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        MsiSetInternalUI(uilevel, NULL);
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
     MsiCloseHandle(hdb);
 
+    buf[0] = 0;
+    size = MAX_PATH;
+    r = MsiGetProperty(hpkg, "UILevel", buf, &size);
+    ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+    ok( !lstrcmp(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+    buf[0] = 0;
+    size = MAX_PATH;
+    r = MsiGetProperty(hpkg, "UILevel", buf, &size);
+    ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+    ok( !lstrcmp(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
+
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "DATABASE", buf, &size);
     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
     ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
 
     RegOpenKey(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\MS Setup (ACME)\\User Info", &hkey1);
-
-    RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hkey2);
+    RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey2);
 
     size = MAX_PATH;
     type = REG_SZ;
@@ -9365,14 +5560,11 @@ static void test_installprops(void)
         RegQueryValueEx(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
     }
 
-    /* win9x doesn't set this */
-    if (*path)
-    {
-        size = MAX_PATH;
-        r = MsiGetProperty(hpkg, "USERNAME", buf, &size);
-        ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
-        ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
-    }
+    buf[0] = 0;
+    size = MAX_PATH;
+    r = MsiGetProperty(hpkg, "USERNAME", buf, &size);
+    ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+    ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
 
     size = MAX_PATH;
     type = REG_SZ;
@@ -9386,59 +5578,297 @@ static void test_installprops(void)
 
     if (*path)
     {
+        buf[0] = 0;
         size = MAX_PATH;
         r = MsiGetProperty(hpkg, "COMPANYNAME", buf, &size);
         ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
         ok( !lstrcmp(buf, path), "Expected %s, got %s\n", path, buf);
     }
 
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "VersionDatabase", buf, &size);
     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
     trace("VersionDatabase = %s\n", buf);
 
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "VersionMsi", buf, &size);
     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
     trace("VersionMsi = %s\n", buf);
 
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "Date", buf, &size);
     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
     trace("Date = %s\n", buf);
 
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "Time", buf, &size);
     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
     trace("Time = %s\n", buf);
 
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "PackageCode", buf, &size);
     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
     trace("PackageCode = %s\n", buf);
 
+    buf[0] = 0;
+    size = MAX_PATH;
+    r = MsiGetProperty(hpkg, "ComputerName", buf, &size);
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
+    trace("ComputerName = %s\n", buf);
+
     langid = GetUserDefaultLangID();
     sprintf(path, "%d", langid);
 
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "UserLanguageID", buf, &size);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS< got %d\n", r);
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     ok( !lstrcmpA(buf, path), "Expected \"%s\", got \"%s\"\n", path, buf);
 
     res = GetSystemMetrics(SM_CXSCREEN);
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "ScreenX", buf, &size);
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf));
 
     res = GetSystemMetrics(SM_CYSCREEN);
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "ScreenY", buf, &size);
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r);
     ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf));
 
+    if (pGetSystemInfo && pSHGetFolderPathA)
+    {
+        pGetSystemInfo(&si);
+        if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+        {
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "Intel", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            ok(buf[0], "property not set\n");
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            ok(buf[0], "property not set\n");
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "Msix64", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            ok(buf[0], "property not set\n");
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "System64Folder", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            GetSystemDirectoryA(path, MAX_PATH);
+            if (size) buf[size - 1] = 0;
+            ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "SystemFolder", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            pGetSystemWow64DirectoryA(path, MAX_PATH);
+            if (size) buf[size - 1] = 0;
+            ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "ProgramFiles64Folder", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path);
+            if (size) buf[size - 1] = 0;
+            ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
+            if (size) buf[size - 1] = 0;
+            ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "CommonFiles64Folder", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path);
+            if (size) buf[size - 1] = 0;
+            ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path);
+            if (size) buf[size - 1] = 0;
+            ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+            buf[0] = 0;
+            size = MAX_PATH;
+            r = MsiGetProperty(hpkg, "VersionNT64", buf, &size);
+            ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+            ok(buf[0], "property not set\n");
+        }
+        else if (S(U(si)).wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
+        {
+            if (!is_wow64)
+            {
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "Intel", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(buf[0], "property not set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "Msix64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "System64Folder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "SystemFolder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                GetSystemDirectoryA(path, MAX_PATH);
+                if (size) buf[size - 1] = 0;
+                ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "ProgramFiles64Folder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path);
+                if (size) buf[size - 1] = 0;
+                ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "CommonFiles64Folder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, path);
+                if (size) buf[size - 1] = 0;
+                ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "VersionNT64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+            }
+            else
+            {
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "Intel", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(buf[0], "property not set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "MsiAMD64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(buf[0], "property not set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "Msix64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(buf[0], "property not set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "System64Folder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                GetSystemDirectoryA(path, MAX_PATH);
+                if (size) buf[size - 1] = 0;
+                ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "SystemFolder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                pGetSystemWow64DirectoryA(path, MAX_PATH);
+                if (size) buf[size - 1] = 0;
+                ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "ProgramFilesFolder64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "ProgramFilesFolder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
+                if (size) buf[size - 1] = 0;
+                ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "CommonFilesFolder64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(!buf[0], "property set\n");
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "CommonFilesFolder", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                pSHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, path);
+                if (size) buf[size - 1] = 0;
+                ok(!lstrcmpiA(path, buf), "expected \"%s\", got \"%s\"\n", path, buf);
+
+                buf[0] = 0;
+                size = MAX_PATH;
+                r = MsiGetProperty(hpkg, "VersionNT64", buf, &size);
+                ok(r == ERROR_SUCCESS, "failed to get property: %d\n", r);
+                ok(buf[0], "property not set\n");
+            }
+        }
+    }
+
     CloseHandle(hkey1);
     CloseHandle(hkey2);
     MsiCloseHandle(hpkg);
     DeleteFile(msifile);
+    MsiSetInternalUI(uilevel, NULL);
 }
 
 static void test_launchconditions(void)
@@ -9462,14 +5892,22 @@ static void test_launchconditions(void)
     r = add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" );
     ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r );
 
-    hpkg = package_from_db( hdb );
-    ok( hpkg, "failed to create package\n");
+    r = package_from_db( hdb, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
     MsiCloseHandle( hdb );
 
     r = MsiSetProperty( hpkg, "X", "1" );
     ok( r == ERROR_SUCCESS, "failed to set property\n" );
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     /* invalid conditions are ignored */
     r = MsiDoAction( hpkg, "LaunchConditions" );
     ok( r == ERROR_SUCCESS, "cost init failed\n" );
@@ -9492,8 +5930,6 @@ static void test_ccpsearch(void)
     DWORD size = MAX_PATH;
     UINT r;
 
-    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
-
     hdb = create_package_db();
     ok(hdb, "failed to create package database\n");
 
@@ -9509,7 +5945,7 @@ static void test_ccpsearch(void)
     r = create_reglocator_table(hdb);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    r = add_reglocator_entry(hdb, "'CCP_random', 0, 'htmlfile\\shell\\open\\nonexistent', '', 1");
+    r = add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     r = create_drlocator_table(hdb);
@@ -9521,11 +5957,19 @@ static void test_ccpsearch(void)
     r = create_signature_table(hdb);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     MsiCloseHandle(hdb);
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     r = MsiDoAction(hpkg, "CCPSearch");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
@@ -9677,8 +6121,14 @@ static void test_complocator(void)
     r = add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     MsiCloseHandle(hdb);
 
@@ -9716,6 +6166,8 @@ static void test_complocator(void)
     set_component_path("neosodon", MSIINSTALLCONTEXT_MACHINE,
                        "{0B499649-197A-48EF-93D2-AF1C17ED6E90}", NULL, FALSE);
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     r = MsiDoAction(hpkg, "AppSearch");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
@@ -9908,8 +6360,14 @@ static void test_MsiGetSourcePath(void)
     r = MsiDatabaseCommit(hdb);
     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     MsiCloseHandle(hdb);
 
@@ -9951,6 +6409,20 @@ static void test_MsiGetSourcePath(void)
        "Expected path to be unchanged, got \"%s\"\n", path);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
+    ok(size == 0, "Expected 0, got %d\n", size);
+
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
+    ok(size == 0, "Expected 0, got %d\n", size);
+
     /* try SourceDir */
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
@@ -9970,6 +6442,13 @@ static void test_MsiGetSourcePath(void)
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     /* source path does not exist, but the property exists */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
+    ok(size == 0, "Expected 0, got %d\n", size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -9995,6 +6474,8 @@ static void test_MsiGetSourcePath(void)
        "Expected path to be unchanged, got \"%s\"\n", path);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     r = MsiDoAction(hpkg, "CostInitialize");
     ok(r == ERROR_SUCCESS, "cost init failed\n");
 
@@ -10024,15 +6505,19 @@ static void test_MsiGetSourcePath(void)
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     /* source path does not exist, but the property exists */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    todo_wine
-    {
-        ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
-        ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
-    }
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
 
     /* try SubDir after CostInitialize */
     size = MAX_PATH;
@@ -10079,6 +6564,13 @@ static void test_MsiGetSourcePath(void)
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     /* source path does not exist, but the property exists */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -10131,6 +6623,13 @@ static void test_MsiGetSourcePath(void)
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     /* source path does not exist, but the property exists */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -10183,6 +6682,13 @@ static void test_MsiGetSourcePath(void)
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     /* source path does not exist, but the property exists */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -10255,6 +6761,31 @@ static void test_MsiGetSourcePath(void)
     ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
     ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
 
+    /* remove property */
+    r = MsiSetProperty(hpkg, "SourceDir", NULL);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+    /* try SourceDir again */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetSourcePath(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
+    /* set property to a valid directory */
+    r = MsiSetProperty(hpkg, "SOURCEDIR", cwd);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+
+    /* try SOURCEDIR again */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
+    ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
+    ok(!lstrcmpA(path, "kiwi"),
+       "Expected path to be unchanged, got \"%s\"\n", path);
+    ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
+
     MsiCloseHandle(hpkg);
 
     /* compressed source */
@@ -10264,8 +6795,8 @@ static void test_MsiGetSourcePath(void)
 
     set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     /* try TARGETDIR */
     size = MAX_PATH;
@@ -10295,6 +6826,13 @@ static void test_MsiGetSourcePath(void)
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     /* source path nor the property exist */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
+    ok(size == 0, "Expected 0, got %d\n", size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -10351,15 +6889,19 @@ static void test_MsiGetSourcePath(void)
     }
 
     /* source path does not exist, but the property exists */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    todo_wine
-    {
-        ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
-        ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
-    }
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
 
     /* try SubDir after CostInitialize */
     size = MAX_PATH;
@@ -10408,6 +6950,13 @@ static void test_MsiGetSourcePath(void)
     }
 
     /* source path and the property exist */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -10462,6 +7011,13 @@ static void test_MsiGetSourcePath(void)
     }
 
     /* source path and the property exist */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -10516,6 +7072,13 @@ static void test_MsiGetSourcePath(void)
     }
 
     /* source path and the property exist */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SourceDir", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+
     size = MAX_PATH;
     lstrcpyA(path, "kiwi");
     r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
@@ -10598,14 +7161,22 @@ static void test_shortlongsource(void)
 
     MsiDatabaseCommit(hdb);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     MsiCloseHandle(hdb);
 
     CreateDirectoryA("one", NULL);
     CreateDirectoryA("four", NULL);
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     r = MsiDoAction(hpkg, "CostInitialize");
     ok(r == ERROR_SUCCESS, "file cost failed\n");
 
@@ -10738,8 +7309,8 @@ static void test_shortlongsource(void)
 
     set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN);
 
-    hpkg = package_from_db(hdb);
-    ok(hpkg, "failed to create package\n");
+    r = package_from_db(hdb, &hpkg);
+    ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
     MsiCloseHandle(hdb);
 
@@ -10880,7 +7451,7 @@ static void test_shortlongsource(void)
 static void test_sourcedir(void)
 {
     MSIHANDLE hdb, hpkg;
-    CHAR package[10];
+    CHAR package[12];
     CHAR path[MAX_PATH];
     CHAR cwd[MAX_PATH];
     CHAR subsrc[MAX_PATH];
@@ -10900,8 +7471,13 @@ static void test_sourcedir(void)
     r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'");
     ok(r == S_OK, "failed\n");
 
-    sprintf(package, "#%i", hdb);
+    sprintf(package, "#%u", hdb);
     r = MsiOpenPackage(package, &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     /* properties only */
@@ -10922,6 +7498,8 @@ static void test_sourcedir(void)
     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
     ok(size == 0, "Expected 0, got %d\n", size);
 
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
     r = MsiDoAction(hpkg, "CostInitialize");
     ok(r == ERROR_SUCCESS, "file cost failed\n");
 
@@ -10979,6 +7557,23 @@ static void test_sourcedir(void)
     ok(!lstrcmpA(path, ""), "Expected \"\", got \"%s\"\n", path);
     ok(size == 0, "Expected 0, got %d\n", size);
 
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size);
+    ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r);
+    ok(!lstrcmpA(path, "kiwi"), "Expected \"kiwi\", got \"%s\"\n", path);
+    ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
+
+    /* SOURCEDIR after calling MsiGetSourcePath */
+    size = MAX_PATH;
+    lstrcpyA(path, "kiwi");
+    r = MsiGetProperty(hpkg, "SOURCEDIR", path, &size);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    todo_wine {
+    ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path);
+    ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size);
+    }
+
     r = MsiDoAction(hpkg, "ResolveSource");
     ok(r == ERROR_SUCCESS, "file cost failed\n");
 
@@ -11205,8 +7800,10 @@ static void test_sourcedir(void)
        "Expected path to be unchanged, got \"%s\"\n", path);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    MsiCloseHandle(hdb);
     MsiCloseHandle(hpkg);
+
+error:
+    MsiCloseHandle(hdb);
     DeleteFileA(msifile);
 }
 
@@ -11311,9 +7908,7 @@ static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD
                line, idx, ares[idx].gothandle,
                (hfile != INVALID_HANDLE_VALUE));
 
-            ok(lasterr == ares[idx].lasterr ||
-               lasterr == 0xdeadbeef, /* win9x */
-               "(%d, lasterr, %d): Expected %d, got %d\n",
+            ok(lasterr == ares[idx].lasterr, "(%d, lasterr, %d): Expected %d, got %d\n",
                line, idx, ares[idx].lasterr, lasterr);
 
             CloseHandle(hfile);
@@ -11338,11 +7933,9 @@ static void test_access(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     test_file_access(msifile, create_commit);
-
     MsiCloseHandle(hdb);
 
     test_file_access(msifile, create_close);
-
     DeleteFileA(msifile);
 
     r = MsiOpenDatabaseA(msifile, MSIDBOPEN_CREATEDIRECT, &hdb);
@@ -11354,11 +7947,9 @@ static void test_access(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     test_file_access(msifile, create_commit);
-
     MsiCloseHandle(hdb);
 
     test_file_access(msifile, create_close);
-
     DeleteFileA(msifile);
 }
 
@@ -11372,6 +7963,11 @@ static void test_emptypackage(void)
     UINT r;
 
     r = MsiOpenPackageA("", &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     todo_wine
     {
         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -11535,21 +8131,16 @@ static void test_MsiGetProductProperty(void)
     DWORD size;
     LONG res;
     UINT r;
-    SC_HANDLE scm;
-
-    scm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
-    if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
-    {
-        win_skip("Different registry keys on Win9x and WinMe\n");
-        return;
-    }
-    CloseServiceHandle(scm);
+    REGSAM access = KEY_ALL_ACCESS;
 
     GetCurrentDirectoryA(MAX_PATH, path);
     lstrcatA(path, "\\");
 
     create_test_guid(prodcode, prod_squashed);
 
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
+
     r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
@@ -11588,14 +8179,20 @@ static void test_MsiGetProductProperty(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     if (res == ERROR_ACCESS_DENIED)
     {
         skip("Not enough rights to perform tests\n");
@@ -11605,7 +8202,7 @@ static void test_MsiGetProductProperty(void)
     }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
-    res = RegCreateKeyA(userkey, "InstallProperties", &props);
+    res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     lstrcpyA(val, path);
@@ -11740,11 +8337,11 @@ static void test_MsiGetProductProperty(void)
     MsiCloseHandle(hprod);
 
     RegDeleteValueA(props, "LocalPackage");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access);
     RegCloseKey(props);
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access);
     RegCloseKey(userkey);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access);
     RegCloseKey(prodkey);
     DeleteFileA(msifile);
 }
@@ -11757,8 +8354,14 @@ static void test_MsiSetProperty(void)
     DWORD size;
     UINT r;
 
-    hpkg = package_from_db(create_package_db());
-    ok(hpkg != 0, "Expected a valid package\n");
+    r = package_from_db(create_package_db(), &hpkg);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        DeleteFile(msifile);
+        return;
+    }
+    ok(r == ERROR_SUCCESS, "Expected a valid package %u\n", r);
 
     /* invalid hInstall */
     r = MsiSetPropertyA(0, "Prop", "Val");
@@ -11874,51 +8477,31 @@ static void test_MsiApplyMultiplePatches(void)
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
 
     r = pMsiApplyMultiplePatchesA(";", NULL, NULL);
-    todo_wine
-    {
-        if (type == DRIVE_FIXED)
-            ok(r == ERROR_PATH_NOT_FOUND,
-               "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
-        else
-            ok(r == ERROR_INVALID_NAME,
-               "Expected ERROR_INVALID_NAME, got %u\n", r);
-    }
+    if (type == DRIVE_FIXED)
+        todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
+    else
+        ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
 
     r = pMsiApplyMultiplePatchesA("  ;", NULL, NULL);
-    todo_wine
-    {
-        if (type == DRIVE_FIXED)
-            ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED,
-               "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
-        else
-            ok(r == ERROR_INVALID_NAME,
-               "Expected ERROR_INVALID_NAME, got %u\n", r);
-    }
+    if (type == DRIVE_FIXED)
+        todo_wine ok(r == ERROR_PATCH_PACKAGE_OPEN_FAILED, "Expected ERROR_PATCH_PACKAGE_OPEN_FAILED, got %u\n", r);
+    else
+        ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
 
     r = pMsiApplyMultiplePatchesA(";;", NULL, NULL);
-    todo_wine
-    {
-        if (type == DRIVE_FIXED)
-            ok(r == ERROR_PATH_NOT_FOUND,
-               "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
-        else
-            ok(r == ERROR_INVALID_NAME,
-               "Expected ERROR_INVALID_NAME, got %u\n", r);
-    }
+    if (type == DRIVE_FIXED)
+        todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
+    else
+        ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
 
     r = pMsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
 
     r = pMsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
-    todo_wine
-    {
-        if (type == DRIVE_FIXED)
-            ok(r == ERROR_PATH_NOT_FOUND,
-               "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
-        else
-            ok(r == ERROR_INVALID_NAME,
-               "Expected ERROR_INVALID_NAME, got %u\n", r);
-    }
+    if (type == DRIVE_FIXED)
+        todo_wine ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %u\n", r);
+    else
+        ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
 
     r = pMsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
     todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
@@ -11938,6 +8521,277 @@ static void test_MsiApplyPatch(void)
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
 }
 
+static void test_MsiEnumComponentCosts(void)
+{
+    MSIHANDLE hdb, hpkg;
+    char package[12], drive[3];
+    DWORD len;
+    UINT r;
+    int cost, temp;
+
+    hdb = create_package_db();
+    ok( hdb, "failed to create database\n" );
+
+    r = create_property_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create Property table %u\n", r );
+
+    r = add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" );
+    ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
+
+    r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" );
+    ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r );
+
+    r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
+    ok( r == ERROR_SUCCESS, "failed to add directory entry %u\n" , r );
+
+    r = create_media_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create Media table %u\n", r );
+
+    r = add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''");
+    ok( r == ERROR_SUCCESS, "cannot add media entry %u\n", r );
+
+    r = create_file_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create File table %u\n", r );
+
+    r = add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" );
+    ok( r == ERROR_SUCCESS, "cannot add file %u\n", r );
+
+    r = create_component_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create Component table %u\n", r );
+
+    r = add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" );
+    ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
+
+    r = add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" );
+    ok( r == ERROR_SUCCESS, "cannot add component %u\n", r );
+
+    r = create_feature_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create Feature table %u\n", r );
+
+    r = add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" );
+    ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
+
+    r = add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" );
+    ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r );
+
+    r = create_feature_components_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table %u\n", r );
+
+    r = add_feature_components_entry( hdb, "'one', 'one'" );
+    ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
+
+    r = add_feature_components_entry( hdb, "'two', 'two'" );
+    ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r );
+
+    r = create_install_execute_sequence_table( hdb );
+    ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table %u\n", r );
+
+    r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" );
+    ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
+
+    r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" );
+    ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
+
+    r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" );
+    ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
+
+    r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" );
+    ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r );
+
+    MsiDatabaseCommit( hdb );
+
+    sprintf( package, "#%u", hdb );
+    r = MsiOpenPackageA( package, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
+
+    r = MsiEnumComponentCostsA( 0, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    r = MsiEnumComponentCostsA( hpkg, NULL, 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    todo_wine ok( r == ERROR_INVALID_HANDLE_STATE, "Expected ERROR_INVALID_HANDLE_STATE, got %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, NULL, &len, &cost, &temp );
+    ok( r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r );
+
+    MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
+
+    r = MsiDoAction( hpkg, "CostInitialize" );
+    ok( r == ERROR_SUCCESS, "CostInitialize failed %u\n", r );
+
+    r = MsiDoAction( hpkg, "FileCost" );
+    ok( r == ERROR_SUCCESS, "FileCost failed %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
+
+    r = MsiDoAction( hpkg, "CostFinalize" );
+    ok( r == ERROR_SUCCESS, "CostFinalize failed %u\n", r );
+
+    /* contrary to what msdn says InstallValidate must be called too */
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    todo_wine ok( r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %u\n", r );
+
+    r = MsiDoAction( hpkg, "InstallValidate" );
+    ok( r == ERROR_SUCCESS, "InstallValidate failed %u\n", r );
+
+    len = 0;
+    r = MsiEnumComponentCostsA( hpkg, "three", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %u\n", r );
+
+    len = 0;
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
+    ok( len == 2, "expected len == 2, got %u\n", len );
+
+    len = 2;
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
+    ok( len == 2, "expected len == 2, got %u\n", len );
+
+    len = 2;
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
+    ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %u\n", r );
+    ok( len == 2, "expected len == 2, got %u\n", len );
+
+    /* install state doesn't seem to matter */
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_ABSENT, drive, &len, &cost, &temp );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_SOURCE, drive, &len, &cost, &temp );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
+
+    len = sizeof(drive);
+    drive[0] = 0;
+    cost = temp = 0xdead;
+    r = MsiEnumComponentCostsA( hpkg, "one", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
+    ok( len == 2, "expected len == 2, got %u\n", len );
+    ok( drive[0], "expected a drive\n" );
+    ok( cost && cost != 0xdead, "expected cost > 0, got %d\n", cost );
+    ok( !temp, "expected temp == 0, got %d\n", temp );
+
+    len = sizeof(drive);
+    drive[0] = 0;
+    cost = temp = 0xdead;
+    r = MsiEnumComponentCostsA( hpkg, "two", 0, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
+    ok( len == 2, "expected len == 2, got %u\n", len );
+    ok( drive[0], "expected a drive\n" );
+    ok( !cost, "expected cost == 0, got %d\n", cost );
+    ok( !temp, "expected temp == 0, got %d\n", temp );
+
+    len = sizeof(drive);
+    drive[0] = 0;
+    cost = temp = 0xdead;
+    r = MsiEnumComponentCostsA( hpkg, "", 0, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
+    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
+    ok( len == 2, "expected len == 2, got %u\n", len );
+    ok( drive[0], "expected a drive\n" );
+    ok( !cost, "expected cost == 0, got %d\n", cost );
+    ok( temp && temp != 0xdead, "expected temp > 0, got %d\n", temp );
+
+    /* increased index */
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "one", 1, INSTALLSTATE_LOCAL, drive, &len, &cost, &temp );
+    ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
+
+    len = sizeof(drive);
+    r = MsiEnumComponentCostsA( hpkg, "", 1, INSTALLSTATE_UNKNOWN, drive, &len, &cost, &temp );
+    ok( r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r );
+
+    MsiCloseHandle( hpkg );
+error:
+    MsiCloseHandle( hdb );
+    DeleteFileA( msifile );
+}
+
+static void test_MsiDatabaseCommit(void)
+{
+    UINT r;
+    MSIHANDLE hdb, hpkg = 0;
+    char buf[32], package[12];
+    DWORD sz;
+
+    hdb = create_package_db();
+    ok( hdb, "failed to create database\n" );
+
+    r = create_property_table( hdb );
+    ok( r == ERROR_SUCCESS, "can't create Property table %u\n", r );
+
+    sprintf( package, "#%u", hdb );
+    r = MsiOpenPackage( package, &hpkg );
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    r = MsiSetPropertyA( hpkg, "PROP", "value" );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    buf[0] = 0;
+    sz = sizeof(buf);
+    r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
+    ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
+    ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
+
+    r = MsiDatabaseCommit( hdb );
+    ok( r == ERROR_SUCCESS, "MsiDatabaseCommit returned %u\n", r );
+
+    buf[0] = 0;
+    sz = sizeof(buf);
+    r = MsiGetPropertyA( hpkg, "PROP", buf, &sz );
+    ok( r == ERROR_SUCCESS, "MsiGetPropertyA returned %u\n", r );
+    ok( !lstrcmpA( buf, "value" ), "got \"%s\"\n", buf );
+
+    MsiCloseHandle( hpkg );
+error:
+    MsiCloseHandle( hdb );
+    DeleteFileA( msifile );
+}
+
 START_TEST(package)
 {
     STATEMGRSTATUS status;
@@ -11945,12 +8799,18 @@ START_TEST(package)
 
     init_functionpointers();
 
+    if (pIsWow64Process)
+        pIsWow64Process(GetCurrentProcess(), &is_wow64);
+
     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
 
     /* Create a restore point ourselves so we circumvent the multitude of restore points
      * that would have been created by all the installation and removal tests.
+     *
+     * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
+     * creation of restore points.
      */
-    if (pSRSetRestorePointA)
+    if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
     {
         memset(&status, 0, sizeof(status));
         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
@@ -11987,8 +8847,10 @@ START_TEST(package)
     test_MsiSetProperty();
     test_MsiApplyMultiplePatches();
     test_MsiApplyPatch();
+    test_MsiEnumComponentCosts();
+    test_MsiDatabaseCommit();
 
-    if (pSRSetRestorePointA && ret)
+    if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
     {
         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
         if (ret)