|
|
|
@@ -124,6 +124,8 @@ static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
|
|
|
|
|
"MoveFiles\t\t1700\n"
|
|
|
|
|
"InstallFiles\t\t4000\n"
|
|
|
|
|
"DuplicateFiles\t\t4500\n"
|
|
|
|
|
"WriteEnvironmentStrings\t\t4550\n"
|
|
|
|
|
"CreateShortcuts\t\t4600\n"
|
|
|
|
|
"InstallServices\t\t5000\n"
|
|
|
|
|
"InstallFinalize\t\t6600\n"
|
|
|
|
|
"InstallInitialize\t\t1500\n"
|
|
|
|
@@ -159,6 +161,24 @@ static const CHAR property_dat[] = "Property\tValue\n"
|
|
|
|
|
"SERVNAME\tTestService\n"
|
|
|
|
|
"SERVDISP\tTestServiceDisp\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
|
|
|
|
|
"s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
|
|
|
|
|
"Shortcut\tShortcut\n"
|
|
|
|
|
"Shortcut\tMSITESTDIR\tShortcut\tcomponent\tShortcut\t\tShortcut\t\t\t\t\t\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR environment_dat[] = "Environment\tName\tValue\tComponent_\n"
|
|
|
|
|
"s72\tl255\tL255\ts72\n"
|
|
|
|
|
"Environment\tEnvironment\n"
|
|
|
|
|
"Var1\t=-MSITESTVAR1\t1\tOne\n"
|
|
|
|
|
"Var2\tMSITESTVAR2\t1\tOne\n"
|
|
|
|
|
"Var3\t=-MSITESTVAR3\t1\tOne\n"
|
|
|
|
|
"Var4\tMSITESTVAR4\t1\tOne\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n"
|
|
|
|
|
"s38\ti2\tS255\n"
|
|
|
|
|
"Condition\tFeature_\tLevel\n"
|
|
|
|
|
"One\t4\t1\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR up_property_dat[] = "Property\tValue\n"
|
|
|
|
|
"s72\tl0\n"
|
|
|
|
|
"Property\tProperty\n"
|
|
|
|
@@ -381,6 +401,21 @@ static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\t
|
|
|
|
|
"Media\tDiskId\n"
|
|
|
|
|
"1\t1\t\t\tDISK1\t\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR rofc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
|
|
|
|
|
"s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
|
|
|
|
|
"File\tFile\n"
|
|
|
|
|
"maximus\tmaximus\tmaximus\t500\t\t\t16384\t1";
|
|
|
|
|
|
|
|
|
|
static const CHAR rofc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
|
|
|
|
|
"i2\ti4\tL64\tS255\tS32\tS72\n"
|
|
|
|
|
"Media\tDiskId\n"
|
|
|
|
|
"1\t1\t\ttest1.cab\tDISK1\t\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR lus2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
|
|
|
|
|
"i2\ti4\tL64\tS255\tS32\tS72\n"
|
|
|
|
|
"Media\tDiskId\n"
|
|
|
|
|
"1\t1\t\t#test1.cab\tDISK1\t\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
|
|
|
|
|
"s72\tS255\tI2\n"
|
|
|
|
|
"InstallExecuteSequence\tAction\n"
|
|
|
|
@@ -851,6 +886,32 @@ static const CHAR ai_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion
|
|
|
|
|
"file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
|
|
|
|
|
"service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
|
|
|
|
|
|
|
|
|
|
static const CHAR ip_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
|
|
|
|
|
"s72\tS255\tI2\n"
|
|
|
|
|
"InstallExecuteSequence\tAction\n"
|
|
|
|
|
"CostFinalize\t\t1000\n"
|
|
|
|
|
"ValidateProductID\t\t700\n"
|
|
|
|
|
"CostInitialize\t\t800\n"
|
|
|
|
|
"FileCost\t\t900\n"
|
|
|
|
|
"RemoveFiles\t\t3500\n"
|
|
|
|
|
"InstallFiles\t\t4000\n"
|
|
|
|
|
"RegisterUser\t\t6000\n"
|
|
|
|
|
"RegisterProduct\t\t6100\n"
|
|
|
|
|
"PublishFeatures\t\t6300\n"
|
|
|
|
|
"PublishProduct\t\t6400\n"
|
|
|
|
|
"InstallFinalize\t\t6600\n"
|
|
|
|
|
"InstallInitialize\t\t1500\n"
|
|
|
|
|
"ProcessComponents\t\t1600\n"
|
|
|
|
|
"UnpublishFeatures\t\t1800\n"
|
|
|
|
|
"InstallValidate\t\t1400\n"
|
|
|
|
|
"LaunchConditions\t\t100\n"
|
|
|
|
|
"TestInstalledProp\tInstalled AND NOT REMOVE\t950\n";
|
|
|
|
|
|
|
|
|
|
static const CHAR ip_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
|
|
|
|
|
"s72\ti2\tS64\tS0\tS255\n"
|
|
|
|
|
"CustomAction\tAction\n"
|
|
|
|
|
"TestInstalledProp\t19\t\tTest failed\t\n";
|
|
|
|
|
|
|
|
|
|
typedef struct _msi_table
|
|
|
|
|
{
|
|
|
|
|
const CHAR *filename;
|
|
|
|
@@ -875,6 +936,45 @@ static const msi_table tables[] =
|
|
|
|
|
ADD_TABLE(service_control)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table sc_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(feature),
|
|
|
|
|
ADD_TABLE(feature_comp),
|
|
|
|
|
ADD_TABLE(file),
|
|
|
|
|
ADD_TABLE(install_exec_seq),
|
|
|
|
|
ADD_TABLE(media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
ADD_TABLE(shortcut)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table ps_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(feature),
|
|
|
|
|
ADD_TABLE(feature_comp),
|
|
|
|
|
ADD_TABLE(file),
|
|
|
|
|
ADD_TABLE(install_exec_seq),
|
|
|
|
|
ADD_TABLE(media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
ADD_TABLE(condition)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table env_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(feature),
|
|
|
|
|
ADD_TABLE(feature_comp),
|
|
|
|
|
ADD_TABLE(file),
|
|
|
|
|
ADD_TABLE(install_exec_seq),
|
|
|
|
|
ADD_TABLE(media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
ADD_TABLE(environment)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table up_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(component),
|
|
|
|
@@ -1078,6 +1178,18 @@ static const msi_table rof_tables[] =
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table rofc_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(rof_component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(rof_feature),
|
|
|
|
|
ADD_TABLE(rof_feature_comp),
|
|
|
|
|
ADD_TABLE(rofc_file),
|
|
|
|
|
ADD_TABLE(install_exec_seq),
|
|
|
|
|
ADD_TABLE(rofc_media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table sdp_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(rof_component),
|
|
|
|
@@ -1166,6 +1278,42 @@ static const msi_table ppc_tables[] =
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table lus0_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(ci_component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(rof_feature),
|
|
|
|
|
ADD_TABLE(rof_feature_comp),
|
|
|
|
|
ADD_TABLE(rof_file),
|
|
|
|
|
ADD_TABLE(pp_install_exec_seq),
|
|
|
|
|
ADD_TABLE(rof_media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table lus1_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(ci_component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(rof_feature),
|
|
|
|
|
ADD_TABLE(rof_feature_comp),
|
|
|
|
|
ADD_TABLE(rof_file),
|
|
|
|
|
ADD_TABLE(pp_install_exec_seq),
|
|
|
|
|
ADD_TABLE(rofc_media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table lus2_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(ci_component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(rof_feature),
|
|
|
|
|
ADD_TABLE(rof_feature_comp),
|
|
|
|
|
ADD_TABLE(rof_file),
|
|
|
|
|
ADD_TABLE(pp_install_exec_seq),
|
|
|
|
|
ADD_TABLE(lus2_media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table tp_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(tp_component),
|
|
|
|
@@ -1378,6 +1526,43 @@ static const msi_table pc_tables[] =
|
|
|
|
|
ADD_TABLE(property)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table ip_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(feature),
|
|
|
|
|
ADD_TABLE(feature_comp),
|
|
|
|
|
ADD_TABLE(file),
|
|
|
|
|
ADD_TABLE(ip_install_exec_seq),
|
|
|
|
|
ADD_TABLE(ip_custom_action),
|
|
|
|
|
ADD_TABLE(media),
|
|
|
|
|
ADD_TABLE(property)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table fiu_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(rof_component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(rof_feature),
|
|
|
|
|
ADD_TABLE(rof_feature_comp),
|
|
|
|
|
ADD_TABLE(rof_file),
|
|
|
|
|
ADD_TABLE(pp_install_exec_seq),
|
|
|
|
|
ADD_TABLE(rof_media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const msi_table fiuc_tables[] =
|
|
|
|
|
{
|
|
|
|
|
ADD_TABLE(rof_component),
|
|
|
|
|
ADD_TABLE(directory),
|
|
|
|
|
ADD_TABLE(rof_feature),
|
|
|
|
|
ADD_TABLE(rof_feature_comp),
|
|
|
|
|
ADD_TABLE(rofc_file),
|
|
|
|
|
ADD_TABLE(pp_install_exec_seq),
|
|
|
|
|
ADD_TABLE(rofc_media),
|
|
|
|
|
ADD_TABLE(property),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* cabinet definitions */
|
|
|
|
|
|
|
|
|
|
/* make the max size large so there is only one cab file */
|
|
|
|
@@ -2578,6 +2763,219 @@ static void test_readonlyfile(void)
|
|
|
|
|
DeleteFile(msifile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_readonlyfile_cab(void)
|
|
|
|
|
{
|
|
|
|
|
UINT r;
|
|
|
|
|
DWORD size;
|
|
|
|
|
HANDLE file;
|
|
|
|
|
CHAR path[MAX_PATH];
|
|
|
|
|
CHAR buf[16];
|
|
|
|
|
|
|
|
|
|
CreateDirectoryA("msitest", NULL);
|
|
|
|
|
create_file("maximus", 500);
|
|
|
|
|
create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
|
|
|
|
|
DeleteFile("maximus");
|
|
|
|
|
|
|
|
|
|
create_database(msifile, rofc_tables, sizeof(rofc_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
|
|
|
|
|
|
lstrcpy(path, PROG_FILES_DIR);
|
|
|
|
|
lstrcat(path, "\\msitest");
|
|
|
|
|
CreateDirectory(path, NULL);
|
|
|
|
|
|
|
|
|
|
lstrcat(path, "\\maximus");
|
|
|
|
|
file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
|
NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
|
|
|
|
|
|
|
|
|
|
WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
|
|
|
|
|
CloseHandle(file);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, NULL);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
memset( buf, 0, sizeof(buf) );
|
|
|
|
|
if ((file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
|
NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
|
|
|
|
|
{
|
|
|
|
|
ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
|
|
|
|
|
CloseHandle(file);
|
|
|
|
|
}
|
|
|
|
|
ok( !lstrcmp( buf, "maximus" ), "Expected file to be overwritten, got '%s'\n", buf );
|
|
|
|
|
ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest", FALSE), "File not installed\n");
|
|
|
|
|
|
|
|
|
|
/* Delete the files in the temp (current) folder */
|
|
|
|
|
delete_cab_files();
|
|
|
|
|
DeleteFile("msitest\\maximus");
|
|
|
|
|
RemoveDirectory("msitest");
|
|
|
|
|
DeleteFile(msifile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
|
|
|
|
|
{
|
|
|
|
|
WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
|
|
|
|
|
IStorage *stg;
|
|
|
|
|
IStream *stm;
|
|
|
|
|
HRESULT hr;
|
|
|
|
|
HANDLE handle;
|
|
|
|
|
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
|
|
|
|
|
hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
|
|
|
|
|
hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
|
{
|
|
|
|
|
IStorage_Release(stg);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
|
|
|
if (handle != INVALID_HANDLE_VALUE)
|
|
|
|
|
{
|
|
|
|
|
DWORD count;
|
|
|
|
|
char buffer[1024];
|
|
|
|
|
if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
|
|
|
|
|
IStream_Write(stm, buffer, count, &count);
|
|
|
|
|
CloseHandle(handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IStream_Release(stm);
|
|
|
|
|
IStorage_Release(stg);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_lastusedsource(void)
|
|
|
|
|
{
|
|
|
|
|
static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
|
|
|
|
|
|
|
|
|
|
UINT r;
|
|
|
|
|
char value[MAX_PATH], path[MAX_PATH];
|
|
|
|
|
DWORD size;
|
|
|
|
|
|
|
|
|
|
if (!pMsiSourceListGetInfoA)
|
|
|
|
|
{
|
|
|
|
|
win_skip("MsiSourceListGetInfoA is not available\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CreateDirectoryA("msitest", NULL);
|
|
|
|
|
create_file("maximus", 500);
|
|
|
|
|
create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
|
|
|
|
|
DeleteFile("maximus");
|
|
|
|
|
|
|
|
|
|
create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
|
|
|
|
|
create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
|
|
|
|
|
create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
|
|
|
|
|
|
/* no cabinet file */
|
|
|
|
|
|
|
|
|
|
size = MAX_PATH;
|
|
|
|
|
lstrcpyA(value, "aaa");
|
|
|
|
|
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
|
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
|
|
|
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
|
|
|
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
lstrcpyA(path, CURR_DIR);
|
|
|
|
|
lstrcatA(path, "\\");
|
|
|
|
|
|
|
|
|
|
size = MAX_PATH;
|
|
|
|
|
lstrcpyA(value, "aaa");
|
|
|
|
|
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
|
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
todo_wine
|
|
|
|
|
{
|
|
|
|
|
ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
|
|
|
|
|
ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
/* separate cabinet file */
|
|
|
|
|
|
|
|
|
|
size = MAX_PATH;
|
|
|
|
|
lstrcpyA(value, "aaa");
|
|
|
|
|
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
|
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
|
|
|
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
|
|
|
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
lstrcpyA(path, CURR_DIR);
|
|
|
|
|
lstrcatA(path, "\\");
|
|
|
|
|
|
|
|
|
|
size = MAX_PATH;
|
|
|
|
|
lstrcpyA(value, "aaa");
|
|
|
|
|
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
|
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
todo_wine
|
|
|
|
|
{
|
|
|
|
|
ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
|
|
|
|
|
ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
size = MAX_PATH;
|
|
|
|
|
lstrcpyA(value, "aaa");
|
|
|
|
|
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
|
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
|
|
|
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
|
|
|
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
|
|
|
|
|
|
/* embedded cabinet stream */
|
|
|
|
|
|
|
|
|
|
add_cabinet_storage("msifile2.msi", "test1.cab");
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
size = MAX_PATH;
|
|
|
|
|
lstrcpyA(value, "aaa");
|
|
|
|
|
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
|
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
todo_wine
|
|
|
|
|
{
|
|
|
|
|
ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
|
|
|
|
|
ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
size = MAX_PATH;
|
|
|
|
|
lstrcpyA(value, "aaa");
|
|
|
|
|
r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
|
|
|
|
|
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
|
|
|
|
|
ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
|
|
|
|
|
ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
|
|
|
|
|
|
|
|
|
|
/* Delete the files in the temp (current) folder */
|
|
|
|
|
delete_cab_files();
|
|
|
|
|
DeleteFile("msitest\\maximus");
|
|
|
|
|
RemoveDirectory("msitest");
|
|
|
|
|
DeleteFile("msifile0.msi");
|
|
|
|
|
DeleteFile("msifile1.msi");
|
|
|
|
|
DeleteFile("msifile2.msi");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_setdirproperty(void)
|
|
|
|
|
{
|
|
|
|
|
UINT r;
|
|
|
|
@@ -4401,10 +4799,7 @@ static void set_transform_summary_info(void)
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
|
|
|
|
|
|
|
|
|
|
r = MsiSummaryInfoPersist(suminfo);
|
|
|
|
|
todo_wine
|
|
|
|
|
{
|
|
|
|
|
ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
|
|
|
|
|
}
|
|
|
|
|
ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
|
|
|
|
|
|
|
|
|
|
r = MsiCloseHandle(suminfo);
|
|
|
|
|
ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
|
|
|
|
@@ -6110,6 +6505,370 @@ static void test_int_widths( void )
|
|
|
|
|
RemoveDirectoryA(tmpdir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_shortcut(void)
|
|
|
|
|
{
|
|
|
|
|
UINT r;
|
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
|
|
create_test_files();
|
|
|
|
|
create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, NULL);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
|
|
|
ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, NULL);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
CoUninitialize();
|
|
|
|
|
|
|
|
|
|
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
|
|
|
|
ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, NULL);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
CoUninitialize();
|
|
|
|
|
|
|
|
|
|
delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\cabout\\new", FALSE);
|
|
|
|
|
delete_pf("msitest\\cabout\\four.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\cabout", FALSE);
|
|
|
|
|
delete_pf("msitest\\changed\\three.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\changed", FALSE);
|
|
|
|
|
delete_pf("msitest\\first\\two.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\first", FALSE);
|
|
|
|
|
delete_pf("msitest\\filename", TRUE);
|
|
|
|
|
delete_pf("msitest\\one.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\service.exe", TRUE);
|
|
|
|
|
delete_pf("msitest\\Shortcut.lnk", TRUE);
|
|
|
|
|
delete_pf("msitest", FALSE);
|
|
|
|
|
delete_test_files();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_envvar(void)
|
|
|
|
|
{
|
|
|
|
|
UINT r;
|
|
|
|
|
HKEY env;
|
|
|
|
|
LONG res;
|
|
|
|
|
DWORD type, size;
|
|
|
|
|
char buffer[16];
|
|
|
|
|
|
|
|
|
|
if (on_win9x)
|
|
|
|
|
{
|
|
|
|
|
win_skip("Environment variables are handled differently on Win9x and WinMe\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
create_test_files();
|
|
|
|
|
create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
|
|
|
|
|
res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
|
|
|
|
|
res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, NULL);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
type = REG_NONE;
|
|
|
|
|
size = sizeof(buffer);
|
|
|
|
|
buffer[0] = 0;
|
|
|
|
|
res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
|
|
|
|
|
ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
|
|
|
|
|
|
|
|
|
|
res = RegDeleteValueA(env, "MSITESTVAR1");
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
|
|
|
|
|
type = REG_NONE;
|
|
|
|
|
size = sizeof(buffer);
|
|
|
|
|
buffer[0] = 0;
|
|
|
|
|
res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
|
|
|
|
|
ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
|
|
|
|
|
|
|
|
|
|
res = RegDeleteValueA(env, "MSITESTVAR2");
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
|
|
|
|
|
res = RegDeleteValueA(env, "MSITESTVAR3");
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
|
|
|
|
|
res = RegDeleteValueA(env, "MSITESTVAR4");
|
|
|
|
|
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
|
|
|
|
|
|
|
|
|
|
RegCloseKey(env);
|
|
|
|
|
|
|
|
|
|
delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\cabout\\new", FALSE);
|
|
|
|
|
delete_pf("msitest\\cabout\\four.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\cabout", FALSE);
|
|
|
|
|
delete_pf("msitest\\changed\\three.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\changed", FALSE);
|
|
|
|
|
delete_pf("msitest\\first\\two.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\first", FALSE);
|
|
|
|
|
delete_pf("msitest\\filename", TRUE);
|
|
|
|
|
delete_pf("msitest\\one.txt", TRUE);
|
|
|
|
|
delete_pf("msitest\\service.exe", TRUE);
|
|
|
|
|
delete_pf("msitest", FALSE);
|
|
|
|
|
delete_test_files();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_preselected(void)
|
|
|
|
|
{
|
|
|
|
|
UINT r;
|
|
|
|
|
|
|
|
|
|
create_test_files();
|
|
|
|
|
create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "ADDLOCAL=One");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
|
|
|
|
|
todo_wine ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
|
|
|
|
|
todo_wine ok(delete_pf("msitest", FALSE), "File not installed\n");
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, NULL);
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
|
|
|
|
|
ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest", FALSE), "File not installed\n");
|
|
|
|
|
delete_test_files();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_installed_prop(void)
|
|
|
|
|
{
|
|
|
|
|
static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
|
|
|
|
|
UINT r;
|
|
|
|
|
|
|
|
|
|
create_test_files();
|
|
|
|
|
create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "FULL=1");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "FULL=1");
|
|
|
|
|
ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
|
|
|
|
|
ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
|
|
|
|
|
ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
|
|
|
|
|
ok(delete_pf("msitest", FALSE), "File not installed\n");
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "REMOVE=ALL");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
delete_test_files();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
|
|
|
|
|
static char rename_ops[] = "PendingFileRenameOperations";
|
|
|
|
|
|
|
|
|
|
static void process_pending_renames(HKEY hkey)
|
|
|
|
|
{
|
|
|
|
|
char *buf, *src, *dst;
|
|
|
|
|
DWORD size;
|
|
|
|
|
LONG ret;
|
|
|
|
|
|
|
|
|
|
ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
|
|
|
|
|
buf = HeapAlloc(GetProcessHeap(), 0, size);
|
|
|
|
|
buf[0] = 0;
|
|
|
|
|
|
|
|
|
|
ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
|
|
|
|
|
ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
|
|
|
|
|
ok(strstr(buf, "msitest\\maximus") != NULL, "Unexpected value \"%s\"\n", buf);
|
|
|
|
|
|
|
|
|
|
for (src = buf; *src; src = dst + strlen(dst) + 1)
|
|
|
|
|
{
|
|
|
|
|
DWORD flags = MOVEFILE_COPY_ALLOWED;
|
|
|
|
|
|
|
|
|
|
dst = src + strlen(src) + 1;
|
|
|
|
|
if (*dst == '!')
|
|
|
|
|
{
|
|
|
|
|
flags |= MOVEFILE_REPLACE_EXISTING;
|
|
|
|
|
dst++;
|
|
|
|
|
}
|
|
|
|
|
if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
|
|
|
|
|
if (*dst)
|
|
|
|
|
{
|
|
|
|
|
if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
|
|
|
|
|
ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
|
|
|
|
|
}
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, buf);
|
|
|
|
|
RegDeleteValueA(hkey, rename_ops);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BOOL file_matches_data(LPCSTR file, LPCSTR data)
|
|
|
|
|
{
|
|
|
|
|
DWORD len, data_len = strlen(data);
|
|
|
|
|
HANDLE handle;
|
|
|
|
|
char buf[128];
|
|
|
|
|
|
|
|
|
|
handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
|
|
|
ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
|
|
|
|
|
|
|
|
|
|
if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
|
|
|
|
|
{
|
|
|
|
|
CloseHandle(handle);
|
|
|
|
|
return !memcmp(buf, data, data_len);
|
|
|
|
|
}
|
|
|
|
|
CloseHandle(handle);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_file_in_use(void)
|
|
|
|
|
{
|
|
|
|
|
UINT r;
|
|
|
|
|
DWORD size;
|
|
|
|
|
HANDLE file;
|
|
|
|
|
HKEY hkey;
|
|
|
|
|
char path[MAX_PATH];
|
|
|
|
|
|
|
|
|
|
if (on_win9x)
|
|
|
|
|
{
|
|
|
|
|
win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
|
|
|
|
|
if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size))
|
|
|
|
|
{
|
|
|
|
|
skip("Pending file rename operations, skipping test\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CreateDirectoryA("msitest", NULL);
|
|
|
|
|
create_file("msitest\\maximus", 500);
|
|
|
|
|
create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
|
|
|
|
|
|
lstrcpy(path, PROG_FILES_DIR);
|
|
|
|
|
lstrcat(path, "\\msitest");
|
|
|
|
|
CreateDirectoryA(path, NULL);
|
|
|
|
|
|
|
|
|
|
lstrcat(path, "\\maximus");
|
|
|
|
|
file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
|
|
|
|
|
ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
|
|
|
|
|
ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
|
|
|
|
|
CloseHandle(file);
|
|
|
|
|
ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
|
|
|
|
|
|
|
|
|
|
process_pending_renames(hkey);
|
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
|
|
|
|
|
|
ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
|
|
|
|
|
ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
|
|
|
|
|
ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "REMOVE=ALL");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
delete_test_files();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void test_file_in_use_cab(void)
|
|
|
|
|
{
|
|
|
|
|
UINT r;
|
|
|
|
|
DWORD size;
|
|
|
|
|
HANDLE file;
|
|
|
|
|
HKEY hkey;
|
|
|
|
|
char path[MAX_PATH];
|
|
|
|
|
|
|
|
|
|
if (on_win9x)
|
|
|
|
|
{
|
|
|
|
|
win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
|
|
|
|
|
if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size))
|
|
|
|
|
{
|
|
|
|
|
skip("Pending file rename operations, skipping test\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CreateDirectoryA("msitest", NULL);
|
|
|
|
|
create_file("maximus", 500);
|
|
|
|
|
create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
|
|
|
|
|
DeleteFile("maximus");
|
|
|
|
|
|
|
|
|
|
create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
|
|
|
|
|
|
|
|
|
|
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
|
|
|
|
|
|
lstrcpy(path, PROG_FILES_DIR);
|
|
|
|
|
lstrcat(path, "\\msitest");
|
|
|
|
|
CreateDirectoryA(path, NULL);
|
|
|
|
|
|
|
|
|
|
lstrcat(path, "\\maximus");
|
|
|
|
|
file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
|
|
|
|
|
ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
|
|
|
|
|
ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
|
|
|
|
|
CloseHandle(file);
|
|
|
|
|
ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
|
|
|
|
|
|
|
|
|
|
process_pending_renames(hkey);
|
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
|
|
|
|
|
|
ok(file_matches_data(path, "maximus"), "Expected file to match\n");
|
|
|
|
|
ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
|
|
|
|
|
ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
|
|
|
|
|
|
|
|
|
|
r = MsiInstallProductA(msifile, "REMOVE=ALL");
|
|
|
|
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
|
|
|
|
|
|
|
|
|
|
delete_cab_files();
|
|
|
|
|
delete_test_files();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
START_TEST(install)
|
|
|
|
|
{
|
|
|
|
|
DWORD len;
|
|
|
|
@@ -6160,6 +6919,7 @@ START_TEST(install)
|
|
|
|
|
test_samesequence();
|
|
|
|
|
test_uiLevelFlags();
|
|
|
|
|
test_readonlyfile();
|
|
|
|
|
test_readonlyfile_cab();
|
|
|
|
|
test_setdirproperty();
|
|
|
|
|
test_cabisextracted();
|
|
|
|
|
test_concurrentinstall();
|
|
|
|
@@ -6190,6 +6950,13 @@ START_TEST(install)
|
|
|
|
|
test_adminimage();
|
|
|
|
|
test_propcase();
|
|
|
|
|
test_int_widths();
|
|
|
|
|
test_shortcut();
|
|
|
|
|
test_envvar();
|
|
|
|
|
test_lastusedsource();
|
|
|
|
|
test_preselected();
|
|
|
|
|
test_installed_prop();
|
|
|
|
|
test_file_in_use();
|
|
|
|
|
test_file_in_use_cab();
|
|
|
|
|
|
|
|
|
|
DeleteFileA(log_file);
|
|
|
|
|
|
|
|
|
|