"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\n"
- "TestService2\tSERVNAME2]\t[SERVDISP2]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService2\t\t-a arg\tservice_comp2\tdescription";
+ "TestService2\t[SERVNAME2]\t[SERVDISP2]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService2\t\t-a arg\tservice_comp2\tdescription\n";
static const char service_install2_dat[] =
"ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
DeleteFileA(msifile);
}
-static void delete_TestService(void)
+static void delete_test_service(const char *name)
{
BOOL ret;
SC_HANDLE manager, service;
manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
ok(manager != NULL, "can't open service manager\n");
- if (!manager)
- return;
-
- service = OpenServiceA(manager, "TestService", GENERIC_ALL);
- ok(service != NULL, "TestService doesn't exist\n");
+ if (!manager) return;
+ service = OpenServiceA(manager, name, GENERIC_ALL);
if (service)
{
ret = DeleteService( service );
ok( ret, "failed to delete service %u\n", GetLastError() );
-
CloseServiceHandle(service);
}
CloseServiceHandle(manager);
-
}
static void test_delete_services(void)
ok(service != NULL, "can't create service %u\n", GetLastError());
CloseServiceHandle(service);
CloseServiceHandle(manager);
- if (!service) goto error;
+ if (!service) return;
create_test_files();
create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
ok(delete_pf("msitest", FALSE), "Directory not created\n");
error:
- delete_TestService();
+ delete_test_service("TestService");
+ delete_test_service("TestService2");
+ delete_test_service("TestService3");
delete_test_files();
DeleteFileA(msifile);
}
service = OpenServiceA(manager, "TestService4", GENERIC_ALL);
ok(service == NULL, "TestService4 installed\n");
- CloseServiceHandle(manager);
res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\TestService", &hKey);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
r = MsiInstallProductA(msifile, "REMOVE=ALL");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ service = OpenServiceA(manager, "TestService", GENERIC_ALL);
+ ok(service != NULL, "TestService deleted\n");
+ CloseServiceHandle(service);
+ CloseServiceHandle(manager);
+
ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "Directory not created\n");
error:
- delete_TestService();
+ delete_test_service("TestService");
delete_test_files();
DeleteFileA(msifile);
}
"UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
"MSIFASTINSTALL\t1\n";
+static const char ci2_property_dat[] =
+ "Property\tValue\n"
+ "s72\tl0\n"
+ "Property\tProperty\n"
+ "INSTALLLEVEL\t3\n"
+ "Manufacturer\tWine\n"
+ "ProductCode\t{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}\n"
+ "ProductName\tMSITEST2\n"
+ "ProductVersion\t1.1.1\n"
+ "UpgradeCode\t{6B60C3CA-B8CA-4FB7-A395-092D98FF5D2A}\n"
+ "MSIFASTINSTALL\t1\n";
+
static const char mcp_component_dat[] =
"Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
"s72\tS38\ts72\ti2\tS255\tS72\n"
"Action\tCondition\tSequence\n"
"s72\tS255\tI2\n"
"InstallExecuteSequence\tAction\n"
- "CostFinalize\t\t1000\n"
"CostInitialize\t\t800\n"
"FileCost\t\t900\n"
- "InstallFiles\t\t4000\n"
- "InstallServices\t\t5000\n"
- "InstallFinalize\t\t6600\n"
- "InstallInitialize\t\t1500\n"
- "RunInstall\t\t1600\n"
+ "CostFinalize\t\t1000\n"
"InstallValidate\t\t1400\n"
- "LaunchConditions\t\t100";
+ "InstallInitialize\t\t1500\n"
+ "RunInstall\tnot Installed\t1550\n"
+ "ProcessComponents\t\t1600\n"
+ "UnpublishFeatures\t\t1800\n"
+ "RemoveFiles\t\t3500\n"
+ "InstallFiles\t\t4000\n"
+ "RegisterProduct\t\t6100\n"
+ "PublishFeatures\t\t6300\n"
+ "PublishProduct\t\t6400\n"
+ "InstallFinalize\t\t6600\n";
static const char ci_custom_action_dat[] =
"Action\tType\tSource\tTarget\tISComments\n"
"s72\ti2\tS64\tS0\tS255\n"
"CustomAction\tAction\n"
- "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
+ "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
static const char ci_component_dat[] =
"Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
ADD_TABLE(ci2_file),
ADD_TABLE(install_exec_seq),
ADD_TABLE(lus0_media),
- ADD_TABLE(property),
+ ADD_TABLE(ci2_property),
};
static const msi_table cl_tables[] =
DeleteFileA(msifile);
}
+static void test_MsiProvideQualifiedComponentEx(void)
+{
+ UINT r;
+ INSTALLSTATE state;
+ char comp[39], comp_squashed[33], comp2[39], comp2_base85[21], comp2_squashed[33];
+ char prod[39], prod_base85[21], prod_squashed[33];
+ char desc[MAX_PATH], buf[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
+ DWORD len = sizeof(buf);
+ REGSAM access = KEY_ALL_ACCESS;
+ HKEY hkey, hkey2, hkey3, hkey4, hkey5;
+ LONG res;
+
+ if (is_process_limited())
+ {
+ skip( "process is limited\n" );
+ return;
+ }
+
+ create_test_guid( comp, comp_squashed );
+ compose_base85_guid( comp2, comp2_base85, comp2_squashed );
+ compose_base85_guid( prod, prod_base85, prod_squashed );
+
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
+ ok( r == ERROR_UNKNOWN_COMPONENT, "got %u\n", r );
+
+ lstrcpyA( keypath, "Software\\Classes\\Installer\\Components\\" );
+ lstrcatA( keypath, comp_squashed );
+
+ if (is_wow64) access |= KEY_WOW64_64KEY;
+ res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey, NULL );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ lstrcpyA( desc, prod_base85 );
+ memcpy( desc + lstrlenA(desc), "feature<\0", sizeof("feature<\0") );
+ res = RegSetValueExA( hkey, "qualifier", 0, REG_MULTI_SZ, (const BYTE *)desc,
+ lstrlenA(prod_base85) + sizeof("feature<\0") );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
+ ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
+
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
+ ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
+
+ state = MsiQueryProductStateA( prod );
+ ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
+
+ lstrcpyA( keypath, "Software\\Classes\\Installer\\Products\\" );
+ lstrcatA( keypath, prod_squashed );
+
+ res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey2, NULL );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ state = MsiQueryProductStateA( prod );
+ ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
+
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
+ todo_wine ok( r == ERROR_UNKNOWN_FEATURE, "got %u\n", r );
+
+ lstrcpyA( keypath, "Software\\Classes\\Installer\\Features\\" );
+ lstrcatA( keypath, prod_squashed );
+
+ res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey3, NULL );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ state = MsiQueryFeatureStateA( prod, "feature" );
+ ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
+
+ res = RegSetValueExA( hkey3, "feature", 0, REG_SZ, (const BYTE *)"", 1 );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ state = MsiQueryFeatureStateA( prod, "feature" );
+ ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
+
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
+ ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
+
+ len = sizeof(buf);
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
+ ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
+
+ lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\" );
+ lstrcatA( keypath, prod_squashed );
+ lstrcatA( keypath, "\\Features" );
+
+ res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey4, NULL );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ res = RegSetValueExA( hkey4, "feature", 0, REG_SZ, (const BYTE *)comp2_base85, sizeof(comp2_base85) );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ state = MsiQueryFeatureStateA( prod, "feature" );
+ ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
+
+ lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\" );
+ lstrcatA( keypath, comp2_squashed );
+
+ res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey5, NULL );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\nosuchfile", sizeof("c:\\nosuchfile") );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ state = MsiQueryFeatureStateA( prod, "feature" );
+ ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
+
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
+ ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
+
+ GetCurrentDirectoryA( MAX_PATH, path );
+ lstrcatA( path, "\\msitest" );
+ CreateDirectoryA( path, NULL );
+ lstrcatA( path, "\\test.txt" );
+ create_file( path, "test", 100 );
+
+ res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)path, lstrlenA(path) + 1 );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ buf[0] = 0;
+ len = sizeof(buf);
+ r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
+ ok( r == ERROR_SUCCESS, "got %u\n", r );
+ ok( len == lstrlenA(path), "got %u\n", len );
+ ok( !lstrcmpA( path, buf ), "got '%s'\n", buf );
+
+ DeleteFileA( "msitest\\text.txt" );
+ RemoveDirectoryA( "msitest" );
+
+ delete_key( hkey5, "", access & KEY_WOW64_64KEY );
+ RegCloseKey( hkey5 );
+ delete_key( hkey4, "", access & KEY_WOW64_64KEY );
+ RegCloseKey( hkey4 );
+ delete_key( hkey3, "", access & KEY_WOW64_64KEY );
+ RegCloseKey( hkey3 );
+ delete_key( hkey2, "", access & KEY_WOW64_64KEY );
+ RegCloseKey( hkey2 );
+ delete_key( hkey, "", access & KEY_WOW64_64KEY );
+ RegCloseKey( hkey );
+}
+
static void test_MsiGetProductCode(void)
{
HKEY compkey, prodkey;
if (r == ERROR_INSTALL_PACKAGE_REJECTED)
{
skip("Not enough rights to perform tests\n");
- DeleteFileA(path);
goto error;
}
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- if (!delete_pf("msitest\\augustus", TRUE))
- trace("concurrent installs not supported\n");
+ ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "Directory not created\n");
r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
INSTALLSTATE_ABSENT);
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(r == ERROR_SUCCESS, "got %u\n", r);
- DeleteFileA(path);
+ r = MsiConfigureProductA("{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}", INSTALLLEVEL_DEFAULT,
+ INSTALLSTATE_ABSENT);
+ ok(r == ERROR_SUCCESS, "got %u\n", r);
error:
+ DeleteFileA(path);
DeleteFileA(msifile);
DeleteFileA("msitest\\msitest\\augustus");
DeleteFileA("msitest\\maximus");
if (pMsiGetComponentPathExA)
test_concurrentinstall();
test_command_line_parsing();
+ test_MsiProvideQualifiedComponentEx();
SetCurrentDirectoryA(prev_path);
}