[MSI_WINETEST]
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 14 May 2012 21:41:45 +0000 (21:41 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 14 May 2012 21:41:45 +0000 (21:41 +0000)
* Sync to Wine 1.5.4.

svn path=/trunk/; revision=56589

rostests/winetests/msi/action.c
rostests/winetests/msi/automation.c
rostests/winetests/msi/db.c
rostests/winetests/msi/msi.c
rostests/winetests/msi/package.c

index 3743e50..2b482df 100644 (file)
@@ -73,7 +73,8 @@ static const char component_dat[] =
     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
     "component\t\tMSITESTDIR\t0\t1\tfile\n"
-    "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
+    "service_comp\t{935A0A91-22A3-4F87-BCA8-928FFDFE2353}\tMSITESTDIR\t0\t\tservice_file\n"
+    "service_comp2\t{3F7B04A4-9521-4649-BDC9-0C8722740A49}\tMSITESTDIR\t0\t\tservice_file2";
 
 static const char directory_dat[] =
     "Directory\tDirectory_Parent\tDefaultDir\n"
@@ -109,7 +110,8 @@ static const char feature_comp_dat[] =
     "Three\tThree\n"
     "Two\tTwo\n"
     "feature\tcomponent\n"
-    "service_feature\tservice_comp\n";
+    "service_feature\tservice_comp\n"
+    "service_feature\tservice_comp2";
 
 static const char file_dat[] =
     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
@@ -121,7 +123,8 @@ static const char file_dat[] =
     "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
     "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
     "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
-    "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
+    "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t6\n"
+    "service_file2\tservice_comp2\tservice2.exe\t100\t\t\t8192\t7";
 
 static const char install_exec_seq_dat[] =
     "Action\tCondition\tSequence\n"
@@ -149,7 +152,7 @@ static const char media_dat[] =
     "i2\ti4\tL64\tS255\tS32\tS72\n"
     "Media\tDiskId\n"
     "1\t3\t\t\tDISK1\t\n"
-    "2\t5\t\tmsitest.cab\tDISK2\t\n";
+    "2\t7\t\tmsitest.cab\tDISK2\t\n";
 
 static const char property_dat[] =
     "Property\tValue\n"
@@ -172,7 +175,9 @@ static const char property_dat[] =
     "AdminProperties\tPOSTADMIN\n"
     "ROOTDRIVE\tC:\\\n"
     "SERVNAME\tTestService\n"
+    "SERVNAME2\tTestService2\n"
     "SERVDISP\tTestServiceDisp\n"
+    "SERVDISP2\tTestServiceDisp2\n"
     "MSIFASTINSTALL\t1\n";
 
 static const char environment_dat[] =
@@ -211,13 +216,15 @@ static const char service_install_dat[] =
     "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
     "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
     "ServiceInstall\tServiceInstall\n"
-    "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService\t\t-a arg\tservice_comp\tdescription";
+    "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService\t\t-a arg\tservice_comp\tdescription\n"
+    "TestService2\tSERVNAME2]\t[SERVDISP2]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService2\t\t-a arg\tservice_comp2\tdescription";
 
 static const char service_control_dat[] =
     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
     "s72\tl255\ti2\tL255\tI2\ts72\n"
     "ServiceControl\tServiceControl\n"
-    "ServiceControl\tTestService\t8\t\t0\tservice_comp";
+    "ServiceControl\tTestService3\t8\t\t0\tservice_comp\n"
+    "ServiceControl2\tTestService3\t128\t\t0\tservice_comp2";
 
 static const char sss_service_control_dat[] =
     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
@@ -254,11 +261,13 @@ static const char sds_install_exec_seq_dat[] =
     "CostFinalize\t\t1000\n"
     "InstallValidate\t\t1400\n"
     "InstallInitialize\t\t1500\n"
-    "DeleteServices\tInstalled\t5000\n"
+    "StopServices\t\t5000\n"
+    "DeleteServices\t\t5050\n"
     "MoveFiles\t\t5100\n"
     "InstallFiles\t\t5200\n"
     "DuplicateFiles\t\t5300\n"
-    "InstallServices\tNOT Installed\t5400\n"
+    "InstallServices\t\t5400\n"
+    "StartServices\t\t5450\n"
     "RegisterProduct\t\t5500\n"
     "PublishFeatures\t\t5600\n"
     "PublishProduct\t\t5700\n"
@@ -2181,6 +2190,7 @@ static void create_test_files(void)
 
     create_file("msitest\\filename", 100);
     create_file("msitest\\service.exe", 100);
+    create_file("msitest\\service2.exe", 100);
 
     DeleteFileA("four.txt");
     DeleteFileA("five.txt");
@@ -2208,6 +2218,7 @@ static void delete_test_files(void)
     DeleteFileA("msitest\\first\\two.txt");
     DeleteFileA("msitest\\one.txt");
     DeleteFileA("msitest\\service.exe");
+    DeleteFileA("msitest\\service2.exe");
     DeleteFileA("msitest\\filename");
     RemoveDirectoryA("msitest\\second");
     RemoveDirectoryA("msitest\\first");
@@ -4706,6 +4717,7 @@ static void test_envvar(void)
     delete_pf("msitest\\filename", TRUE);
     delete_pf("msitest\\one.txt", TRUE);
     delete_pf("msitest\\service.exe", TRUE);
+    delete_pf("msitest\\service2.exe", TRUE);
     delete_pf("msitest", FALSE);
 
 error:
@@ -4830,6 +4842,7 @@ static void test_start_services(void)
     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+    ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
     ok(delete_pf("msitest", FALSE), "Directory not created\n");
 
     delete_test_files();
@@ -4853,6 +4866,8 @@ static void test_start_services(void)
 static void test_delete_services(void)
 {
     UINT r;
+    SC_HANDLE manager, service;
+    DWORD error;
 
     if (is_process_limited())
     {
@@ -4860,6 +4875,18 @@ static void test_delete_services(void)
         return;
     }
 
+    manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+    ok(manager != NULL, "can't open service manager %u\n", GetLastError());
+    if (!manager) return;
+
+    service = CreateServiceA(manager, "TestService3", "TestService3",
+        SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
+        SERVICE_ERROR_NORMAL, "C:\\doesnt_exist.exe", NULL, NULL, NULL, NULL, NULL);
+    ok(service != NULL, "can't create service %u\n", GetLastError());
+    CloseServiceHandle(service);
+    CloseServiceHandle(manager);
+    if (!service) goto error;
+
     create_test_files();
     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
 
@@ -4873,6 +4900,16 @@ static void test_delete_services(void)
     }
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
+    manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+    ok(manager != NULL, "can't open service manager\n");
+    if (!manager) goto error;
+
+    service = OpenServiceA(manager, "TestService3", GENERIC_ALL);
+    error = GetLastError();
+    ok(service == NULL, "TestService3 not deleted\n");
+    ok(error == ERROR_SERVICE_DOES_NOT_EXIST, "wrong error %u\n", error);
+    CloseServiceHandle(manager);
+
     r = MsiInstallProductA(msifile, "REMOVE=ALL");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
@@ -4887,6 +4924,7 @@ static void test_delete_services(void)
     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+    ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
     ok(delete_pf("msitest", FALSE), "Directory not created\n");
 
 error:
@@ -4928,6 +4966,7 @@ static void test_self_registration(void)
     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+    ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
     ok(delete_pf("msitest", FALSE), "Directory not created\n");
 
 error:
@@ -5034,6 +5073,7 @@ static void test_validate_product_id(void)
     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+    ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
     ok(delete_pf("msitest", FALSE), "Directory not created\n");
 
 error:
index f062368..630ff76 100644 (file)
@@ -489,113 +489,79 @@ static DISPID get_dispid( IDispatch *disp, const char *name )
     return id;
 }
 
+typedef struct {
+    DISPID did;
+    const char *name;
+    BOOL todo;
+} get_did_t;
+
+static const get_did_t get_did_data[] = {
+    { 1,  "CreateRecord" },
+    { 2,  "OpenPackage" },
+    { 3,  "OpenProduct" },
+    { 4,  "OpenDatabase" },
+    { 5,  "SummaryInformation" },
+    { 6,  "UILevel" },
+    { 7,  "EnableLog" },
+    { 8,  "InstallProduct" },
+    { 9,  "Version" },
+    { 10, "LastErrorRecord" },
+    { 11, "RegistryValue" },
+    { 12, "Environment" },
+    { 13, "FileAttributes" },
+    { 15, "FileSize" },
+    { 16, "FileVersion" },
+    { 17, "ProductState" },
+    { 18, "ProductInfo" },
+    { 19, "ConfigureProduct", TRUE },
+    { 20, "ReinstallProduct", TRUE },
+    { 21, "CollectUserInfo", TRUE },
+    { 22, "ApplyPatch", TRUE },
+    { 23, "FeatureParent", TRUE },
+    { 24, "FeatureState", TRUE },
+    { 25, "UseFeature", TRUE },
+    { 26, "FeatureUsageCount", TRUE },
+    { 27, "FeatureUsageDate", TRUE },
+    { 28, "ConfigureFeature", TRUE },
+    { 29, "ReinstallFeature", TRUE },
+    { 30, "ProvideComponent", TRUE },
+    { 31, "ComponentPath", TRUE },
+    { 32, "ProvideQualifiedComponent", TRUE },
+    { 33, "QualifierDescription", TRUE },
+    { 34, "ComponentQualifiers", TRUE },
+    { 35, "Products" },
+    { 36, "Features", TRUE },
+    { 37, "Components", TRUE },
+    { 38, "ComponentClients", TRUE },
+    { 39, "Patches", TRUE },
+    { 40, "RelatedProducts" },
+    { 41, "PatchInfo", TRUE },
+    { 42, "PatchTransforms", TRUE },
+    { 43, "AddSource", TRUE },
+    { 44, "ClearSourceList", TRUE },
+    { 45, "ForceSourceListResolution", TRUE },
+    { 46, "ShortcutTarget", TRUE },
+    { 47, "FileHash", TRUE },
+    { 48, "FileSignatureInfo", TRUE },
+    { 0 }
+};
+
 static void test_dispid(void)
 {
+    const get_did_t *ptr = get_did_data;
     DISPID dispid;
 
-    dispid = get_dispid(pInstaller, "CreateRecord");
-    ok(dispid  == 1, "Expected 1, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "OpenPackage");
-    ok(dispid  == 2, "Expected 2, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "OpenProduct");
-    ok(dispid  == 3, "Expected 3, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "OpenDatabase");
-    ok(dispid == 4, "Expected 4, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "SummaryInformation");
-    ok(dispid == 5, "Expected 5, got %d\n", dispid);
-    dispid = get_dispid( pInstaller, "UILevel" );
-    ok(dispid == 6, "Expected 6, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "EnableLog");
-    ok(dispid == 7, "Expected 7, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "InstallProduct");
-    ok(dispid == 8, "Expected 8, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "Version");
-    ok(dispid == 9, "Expected 9, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "LastErrorRecord");
-    ok(dispid == 10, "Expected 10, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "RegistryValue");
-    ok(dispid == 11, "Expected 11, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "Environment");
-    ok(dispid == 12, "Expected 12, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "FileAttributes");
-    ok(dispid == 13, "Expected 13, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "FileSize");
-    ok(dispid == 15, "Expected 15, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "FileVersion");
-    ok(dispid == 16, "Expected 16, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "ProductState");
-    ok(dispid == 17, "Expected 17, got %d\n", dispid);
-    dispid = get_dispid(pInstaller, "ProductInfo");
-    ok(dispid == 18, "Expected 18, got %d\n", dispid);
-    todo_wine
-    {
-        dispid = get_dispid(pInstaller, "ConfigureProduct");
-        ok(dispid == 19, "Expected 19, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ReinstallProduct");
-        ok(dispid == 20 , "Expected 20, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "CollectUserInfo");
-        ok(dispid == 21, "Expected 21, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ApplyPatch");
-        ok(dispid == 22, "Expected 22, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "FeatureParent");
-        ok(dispid == 23, "Expected 23, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "FeatureState");
-        ok(dispid == 24, "Expected 24, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "UseFeature");
-        ok(dispid == 25, "Expected 25, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "FeatureUsageCount");
-        ok(dispid == 26, "Expected 26, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "FeatureUsageDate");
-        ok(dispid == 27, "Expected 27, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ConfigureFeature");
-        ok(dispid == 28, "Expected 28, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ReinstallFeature");
-        ok(dispid == 29, "Expected 29, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ProvideComponent");
-        ok(dispid == 30, "Expected 30, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ComponentPath");
-        ok(dispid == 31, "Expected 31, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ProvideQualifiedComponent");
-        ok(dispid == 32, "Expected 32, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "QualifierDescription");
-        ok(dispid == 33, "Expected 33, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ComponentQualifiers");
-        ok(dispid == 34, "Expected 34, got %d\n", dispid);
-    }
-    dispid = get_dispid(pInstaller, "Products");
-    ok(dispid == 35, "Expected 35, got %d\n", dispid);
-    todo_wine
-    {
-        dispid = get_dispid(pInstaller, "Features");
-        ok(dispid == 36, "Expected 36, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "Components");
-        ok(dispid == 37, "Expected 37, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ComponentClients");
-        ok(dispid == 38, "Expected 38, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "Patches");
-        ok(dispid == 39, "Expected 39, got %d\n", dispid);
-    }
-    dispid = get_dispid(pInstaller, "RelatedProducts");
-    ok(dispid == 40, "Expected 40, got %d\n", dispid);
-    todo_wine
+    while (ptr->name)
     {
-        dispid = get_dispid(pInstaller, "PatchInfo");
-        ok(dispid == 41, "Expected 41, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "PatchTransforms");
-        ok(dispid == 42, "Expected 42, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "AddSource");
-        ok(dispid == 43, "Expected 43, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ClearSourceList");
-        ok(dispid == 44, "Expected 44, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ForceSourceListResolution");
-        ok(dispid == 45, "Expected 45, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "ShortcutTarget");
-        ok(dispid == 46, "Expected 46, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "FileHash");
-        ok(dispid == 47, "Expected 47, got %d\n", dispid);
-        dispid = get_dispid(pInstaller, "FileSignatureInfo");
-        ok(dispid == 48, "Expected 48, got %d\n", dispid);
+        dispid = get_dispid(pInstaller, ptr->name);
+        if (ptr->todo)
+        todo_wine
+            ok(dispid == ptr->did, "%s: expected %d, got %d\n", ptr->name, ptr->did, dispid);
+        else
+            ok(dispid == ptr->did, "%s: expected %d, got %d\n", ptr->name, ptr->did, dispid);
+        ptr++;
     }
+
     dispid = get_dispid(pInstaller, "RemovePatches");
     ok(dispid == 49 || dispid == -1, "Expected 49 or -1, got %d\n", dispid);
     dispid = get_dispid(pInstaller, "ApplyMultiplePatches");
@@ -1921,7 +1887,7 @@ static void test_Session(IDispatch *pSession)
     ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr);
 
     hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, TRUE);
-    todo_wine ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr);
+    ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr);
     if (hr == DISP_E_EXCEPTION) ok_exception(hr, szModeFlag);
 
     hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTNOW, &bool);
@@ -1929,7 +1895,7 @@ static void test_Session(IDispatch *pSession)
     ok(bool, "Reboot now mode is %d, expected 1\n", bool);
 
     hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, FALSE);  /* set it again so we don't reboot */
-    todo_wine ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr);
+    ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr);
     if (hr == DISP_E_EXCEPTION) ok_exception(hr, szModeFlag);
 
     hr = Session_ModePut(pSession, MSIRUNMODE_MAINTENANCE, TRUE);
index d33eb0c..4c91bd8 100644 (file)
@@ -923,6 +923,30 @@ static void test_viewmodify(void)
     r = MsiViewModify(hview, MSIMODIFY_INSERT_TEMPORARY, hrec );
     ok(r == ERROR_FUNCTION_FAILED, "MsiViewModify failed\n");
 
+    /* try to merge the same record */
+    r = MsiViewExecute(hview, 0);
+    ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
+    r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec );
+    ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
+
+    r = MsiCloseHandle(hrec);
+    ok(r == ERROR_SUCCESS, "failed to close record\n");
+
+    /* try merging a new record */
+    hrec = MsiCreateRecord(3);
+
+    r = MsiRecordSetInteger(hrec, 1, 10);
+    ok(r == ERROR_SUCCESS, "failed to set integer\n");
+    r = MsiRecordSetString(hrec, 2, "pepe");
+    ok(r == ERROR_SUCCESS, "failed to set string\n");
+    r = MsiRecordSetString(hrec, 3, "7654321");
+    ok(r == ERROR_SUCCESS, "failed to set string\n");
+
+    r = MsiViewModify(hview, MSIMODIFY_MERGE, hrec );
+    ok(r == ERROR_SUCCESS, "MsiViewModify failed\n");
+    r = MsiViewExecute(hview, 0);
+    ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
+
     r = MsiCloseHandle(hrec);
     ok(r == ERROR_SUCCESS, "failed to close record\n");
 
index 6ba0e11..da6b446 100644 (file)
@@ -55,6 +55,10 @@ static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
     (LPCSTR, LPCSTR ,DWORD, DWORD);
 static UINT (WINAPI *pMsiGetPatchInfoExA)
     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
+static UINT (WINAPI *pMsiEnumProductsExA)
+    (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
+static UINT (WINAPI *pMsiEnumComponentsExA)
+    (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
 
 static void init_functionpointers(void)
 {
@@ -76,6 +80,8 @@ static void init_functionpointers(void)
     GET_PROC(hmsi, MsiQueryComponentStateA)
     GET_PROC(hmsi, MsiUseFeatureExA)
     GET_PROC(hmsi, MsiGetPatchInfoExA)
+    GET_PROC(hmsi, MsiEnumProductsExA)
+    GET_PROC(hmsi, MsiEnumComponentsExA)
 
     GET_PROC(hadvapi32, ConvertSidToStringSidA)
     GET_PROC(hadvapi32, RegDeleteKeyExA)
@@ -411,6 +417,12 @@ static const struct
     MSIFILEHASHINFO hash;
 } hash_data[] =
 {
+    { "", 0,
+      { HASHSIZE,
+        { 0, 0, 0, 0 },
+      },
+    },
+
     { "abc", 0,
       { HASHSIZE,
         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
@@ -538,8 +550,11 @@ static void create_test_guid(LPSTR prodcode, LPSTR squashed)
     ok(size == 39, "Expected 39, got %d\n", hr);
 
     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
-    squash_guid(guidW, squashedW);
-    WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
+    if (squashed)
+    {
+        squash_guid(guidW, squashedW);
+        WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
+    }
 }
 
 static char *get_user_sid(void)
@@ -1631,10 +1646,10 @@ static void test_MsiQueryComponentState(void)
     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
-    res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
+    res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
-    /* bad INSTALLSTATE_SOURCE */
+    /* registry component */
     state = MAGIC_ERROR;
     SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
@@ -11788,12 +11803,340 @@ static void test_MsiGetFileSignatureInformation(void)
     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
 
+    cert = (const CERT_CONTEXT *)0xdeadbeef;
     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
     todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
+    ok(cert == NULL, "got %p\n", cert);
 
     DeleteFileA( "signature.bin" );
 }
 
+static void test_MsiEnumProductsEx(void)
+{
+    UINT r;
+    DWORD len, index;
+    MSIINSTALLCONTEXT context;
+    char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
+    char product_squashed1[33], product_squashed2[33], product_squashed3[33];
+    char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
+    HKEY key1 = NULL, key2 = NULL, key3 = NULL;
+    REGSAM access = KEY_ALL_ACCESS;
+    char *usersid = get_user_sid();
+
+    if (!pMsiEnumProductsExA)
+    {
+        win_skip("MsiEnumProductsExA not implemented\n");
+        return;
+    }
+
+    create_test_guid( product0, NULL );
+    create_test_guid( product1, product_squashed1 );
+    create_test_guid( product2, product_squashed2 );
+    create_test_guid( product3, product_squashed3 );
+
+    if (is_wow64) access |= KEY_WOW64_64KEY;
+
+    strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
+    strcat( keypath1, product_squashed1 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
+    strcat( keypath2, usersid );
+    strcat( keypath2, "\\Installer\\Products\\" );
+    strcat( keypath2, product_squashed2 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath3, usersid );
+    strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
+    strcat( keypath3, product_squashed3 );
+
+    r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+    ok( len == sizeof(sid), "got %u\n", len );
+
+    r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
+    ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
+    ok( len == sizeof(sid), "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
+    ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
+    ok( len == sizeof(sid), "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    sid[0] = 0;
+    len = 0;
+    r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
+    ok( r == ERROR_MORE_DATA, "got %u\n", r );
+    ok( len, "length unchanged\n" );
+    ok( !sid[0], "got %s\n", sid );
+
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    ok( guid[0], "empty guid\n" );
+    ok( context != 0xdeadbeef, "context unchanged\n" );
+    ok( !len, "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    ok( guid[0], "empty guid\n" );
+    ok( context != 0xdeadbeef, "context unchanged\n" );
+    ok( !len, "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    ok( guid[0], "empty guid\n" );
+    ok( context != 0xdeadbeef, "context unchanged\n" );
+    ok( !len, "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    index = 0;
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
+    {
+        if (!strcmp( product1, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
+            ok( !sid[0], "got \"%s\"\n", sid );
+            ok( !len, "unexpected length %u\n", len );
+        }
+        if (!strcmp( product2, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
+            ok( sid[0], "empty sid\n" );
+            ok( len == strlen(sid), "unexpected length %u\n", len );
+        }
+        if (!strcmp( product3, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
+            ok( sid[0], "empty sid\n" );
+            ok( len == strlen(sid), "unexpected length %u\n", len );
+        }
+        index++;
+        guid[0] = 0;
+        context = 0xdeadbeef;
+        sid[0] = 0;
+        len = sizeof(sid);
+    }
+
+done:
+    delete_key( key1, "", access );
+    delete_key( key2, "", access );
+    delete_key( key3, "", access );
+    RegCloseKey( key1 );
+    RegCloseKey( key2 );
+    RegCloseKey( key3 );
+    LocalFree( usersid );
+}
+
+static void test_MsiEnumComponents(void)
+{
+    UINT r;
+    int found1, found2;
+    DWORD index;
+    char comp1[39], comp2[39], guid[39];
+    char comp_squashed1[33], comp_squashed2[33];
+    char keypath1[MAX_PATH], keypath2[MAX_PATH];
+    REGSAM access = KEY_ALL_ACCESS;
+    char *usersid = get_user_sid();
+    HKEY key1 = NULL, key2 = NULL;
+
+    create_test_guid( comp1, comp_squashed1 );
+    create_test_guid( comp2, comp_squashed2 );
+
+    if (is_wow64) access |= KEY_WOW64_64KEY;
+
+    strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath1, "S-1-5-18\\Components\\" );
+    strcat( keypath1, comp_squashed1 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath2, usersid );
+    strcat( keypath2, "\\Components\\" );
+    strcat( keypath2, comp_squashed2 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+
+    r = MsiEnumComponentsA( 0, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+    index = 0;
+    guid[0] = 0;
+    found1 = found2 = 0;
+    while (!MsiEnumComponentsA( index, guid ))
+    {
+        if (!strcmp( guid, comp1 )) found1 = 1;
+        if (!strcmp( guid, comp2 )) found2 = 1;
+        ok( guid[0], "empty guid\n" );
+        guid[0] = 0;
+        index++;
+    }
+    ok( found1, "comp1 not found\n" );
+    ok( found2, "comp2 not found\n" );
+
+done:
+    delete_key( key1, "", access );
+    delete_key( key2, "", access );
+    RegCloseKey( key1 );
+    RegCloseKey( key2 );
+    LocalFree( usersid );
+}
+
+static void test_MsiEnumComponentsEx(void)
+{
+    UINT r;
+    int found1, found2;
+    DWORD len, index;
+    MSIINSTALLCONTEXT context;
+    char comp1[39], comp2[39], guid[39], sid[128];
+    char comp_squashed1[33], comp_squashed2[33];
+    char keypath1[MAX_PATH], keypath2[MAX_PATH];
+    HKEY key1 = NULL, key2 = NULL;
+    REGSAM access = KEY_ALL_ACCESS;
+    char *usersid = get_user_sid();
+
+    if (!pMsiEnumComponentsExA)
+    {
+        win_skip( "MsiEnumComponentsExA not implemented\n" );
+        return;
+    }
+    create_test_guid( comp1, comp_squashed1 );
+    create_test_guid( comp2, comp_squashed2 );
+
+    if (is_wow64) access |= KEY_WOW64_64KEY;
+
+    strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath1, "S-1-5-18\\Components\\" );
+    strcat( keypath1, comp_squashed1 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath2, usersid );
+    strcat( keypath2, "\\Components\\" );
+    strcat( keypath2, comp_squashed2 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
+                        sizeof("c:\\doesnotexist"));
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    index = 0;
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    found1 = found2 = 0;
+    while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
+    {
+        if (!strcmp( comp1, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
+            ok( !sid[0], "got \"%s\"\n", sid );
+            ok( !len, "unexpected length %u\n", len );
+            found1 = 1;
+        }
+        if (!strcmp( comp2, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
+            ok( sid[0], "empty sid\n" );
+            ok( len == strlen(sid), "unexpected length %u\n", len );
+            found2 = 1;
+        }
+        index++;
+        guid[0] = 0;
+        context = 0xdeadbeef;
+        sid[0] = 0;
+        len = sizeof(sid);
+    }
+    ok( found1, "comp1 not found\n" );
+    ok( found2, "comp2 not found\n" );
+
+    r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+    r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+done:
+    RegDeleteValueA( key2, comp_squashed2 );
+    delete_key( key1, "", access );
+    delete_key( key2, "", access );
+    RegCloseKey( key1 );
+    RegCloseKey( key2 );
+    LocalFree( usersid );
+}
+
 START_TEST(msi)
 {
     init_functionpointers();
@@ -11826,6 +12169,9 @@ START_TEST(msi)
         test_MsiGetPatchInfoEx();
         test_MsiGetPatchInfo();
         test_MsiEnumProducts();
+        test_MsiEnumProductsEx();
+        test_MsiEnumComponents();
+        test_MsiEnumComponentsEx();
     }
     test_MsiGetFileVersion();
     test_MsiGetFileSignatureInformation();
index 9fae1d9..8cf8f27 100644 (file)
@@ -1134,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 );
@@ -1144,6 +1145,7 @@ 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 );
@@ -1153,16 +1155,19 @@ static void test_settargetpath(void)
     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);
@@ -1171,6 +1176,7 @@ 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);
@@ -1179,11 +1185,21 @@ static void test_settargetpath(void)
     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 );
 }
 
@@ -2529,16 +2545,78 @@ 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())
     {
@@ -2921,953 +2999,60 @@ 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 = MsiGetFeatureState(hpkg, "eleven", &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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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");
 
-    r = MsiGetFeatureState(hpkg, "one", NULL, NULL);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-
-    action = 0xdeadbee;
-    r = MsiGetFeatureState(hpkg, "one", NULL, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
-    state = 0xdeadbee;
-    r = MsiGetFeatureState( hpkg, "one", &state, NULL);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
-
-    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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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 );
 
@@ -3898,924 +3083,58 @@ static void test_states(void)
 
     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 = MsiGetFeatureState(hpkg, "eleven", &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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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);
 
@@ -4837,938 +3156,52 @@ static void test_states(void)
     r = package_from_db( hdb, &hpkg );
     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
-    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 = MsiGetFeatureState(hpkg, "eleven", &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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &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_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_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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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, "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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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, "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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    todo_wine 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_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    todo_wine 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_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
-    todo_wine ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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);
+    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);
 
@@ -5790,938 +3223,58 @@ static void test_states(void)
     r = package_from_db( hdb, &hpkg );
     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
-    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 = MsiGetFeatureState(hpkg, "eleven", &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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &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_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_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( 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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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, "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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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, "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( 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_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, "psi", &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);
+    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);
 
@@ -6739,938 +3292,58 @@ static void test_states(void)
     r = package_from_db( hdb, &hpkg );
     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
 
-    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 = MsiGetFeatureState(hpkg, "eleven", &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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_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);
-
-    state = 0xdeadbee;
-    action = 0xdeadbee;
-    r = MsiGetComponentState(hpkg, "psi", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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 = MsiGetFeatureState(hpkg, "eleven", &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_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_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( 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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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, "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( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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_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, "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( 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_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, "psi", &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);
+    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);
 
@@ -9573,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" );
@@ -9767,124 +5439,24 @@ 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, "lyra", &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);
@@ -9895,111 +5467,25 @@ static void test_featureparents(void)
     r = MsiSetFeatureState(hpkg, "nosuchfeature", INSTALLSTATE_ABSENT);
     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %u\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 = MsiGetFeatureState(hpkg, "lyra", &state, &action);
-    ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
-    ok( state == INSTALLSTATE_ABSENT, "Expected lyra INSTALLSTATE_ABSENT, got %d\n", state);
-    ok( action == INSTALLSTATE_ABSENT, "Expected lyra 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);
-    
+    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);
 }
@@ -10015,6 +5501,7 @@ static void test_installprops(void)
     UINT r;
     REGSAM access = KEY_ALL_ACCESS;
     SYSTEM_INFO si;
+    INSTALLUILEVEL uilevel;
 
     if (is_wow64)
         access |= KEY_WOW64_64KEY;
@@ -10023,6 +5510,8 @@ static void test_installprops(void)
     lstrcat(path, "\\");
     lstrcat(path, msifile);
 
+    uilevel = MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_SOURCERESONLY, NULL);
+
     hdb = create_package_db();
     ok( hdb, "failed to create database\n");
 
@@ -10030,6 +5519,7 @@ static void test_installprops(void)
     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
     {
         skip("Not enough rights to perform tests\n");
+        MsiSetInternalUI(uilevel, NULL);
         DeleteFile(msifile);
         return;
     }
@@ -10037,6 +5527,21 @@ static void test_installprops(void)
 
     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);
@@ -10055,6 +5560,7 @@ static void test_installprops(void)
         RegQueryValueEx(hkey2, "RegisteredOwner", NULL, &type, (LPBYTE)path, &size);
     }
 
+    buf[0] = 0;
     size = MAX_PATH;
     r = MsiGetProperty(hpkg, "USERNAME", buf, &size);
     ok( r == ERROR_SUCCESS, "failed to get property: %d\n", r);
@@ -10072,37 +5578,44 @@ 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);
@@ -10111,18 +5624,21 @@ static void test_installprops(void)
     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( !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);
@@ -10133,6 +5649,12 @@ static void test_installprops(void)
         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);
@@ -10203,6 +5725,12 @@ static void test_installprops(void)
         {
             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);
@@ -10265,6 +5793,12 @@ static void test_installprops(void)
             }
             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);
@@ -10334,6 +5868,7 @@ static void test_installprops(void)
     CloseHandle(hkey2);
     MsiCloseHandle(hpkg);
     DeleteFile(msifile);
+    MsiSetInternalUI(uilevel, NULL);
 }
 
 static void test_launchconditions(void)
@@ -10970,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;
@@ -11025,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);
@@ -11077,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);
@@ -11129,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);
@@ -11266,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);
@@ -11322,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;
@@ -11379,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);
@@ -11433,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);
@@ -11487,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);
@@ -13154,6 +8746,52 @@ error:
     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;
@@ -13210,6 +8848,7 @@ START_TEST(package)
     test_MsiApplyMultiplePatches();
     test_MsiApplyPatch();
     test_MsiEnumComponentCosts();
+    test_MsiDatabaseCommit();
 
     if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
     {