static UINT (WINAPI *pMsiQueryComponentStateA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
+static UINT (WINAPI *pMsiSetExternalUIRecord)
+ (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
static UINT (WINAPI *pMsiSourceListEnumSourcesA)
(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
static UINT (WINAPI *pMsiSourceListGetInfoA)
"Component\tComponent\n"
"Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
"Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
- "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\t\tone.txt\n"
+ "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
"Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
"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"
"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"
"SERVNAME\tTestService\n"
"SERVDISP\tTestServiceDisp\n";
+static const CHAR aup_property_dat[] = "Property\tValue\n"
+ "s72\tl0\n"
+ "Property\tProperty\n"
+ "DefaultUIFont\tDlgFont8\n"
+ "HASUIRUN\t0\n"
+ "ALLUSERS\t1\n"
+ "INSTALLLEVEL\t3\n"
+ "InstallMode\tTypical\n"
+ "Manufacturer\tWine\n"
+ "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
+ "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
+ "ProductID\tnone\n"
+ "ProductLanguage\t1033\n"
+ "ProductName\tMSITEST\n"
+ "ProductVersion\t1.1.1\n"
+ "PROMPTROLLBACKCOST\tP\n"
+ "Setup\tSetup\n"
+ "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
+ "AdminProperties\tPOSTADMIN\n"
+ "ROOTDRIVE\tC:\\\n"
+ "SERVNAME\tTestService\n"
+ "SERVDISP\tTestServiceDisp\n";
+
+static const CHAR aup2_property_dat[] = "Property\tValue\n"
+ "s72\tl0\n"
+ "Property\tProperty\n"
+ "DefaultUIFont\tDlgFont8\n"
+ "HASUIRUN\t0\n"
+ "ALLUSERS\t2\n"
+ "INSTALLLEVEL\t3\n"
+ "InstallMode\tTypical\n"
+ "Manufacturer\tWine\n"
+ "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
+ "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
+ "ProductID\tnone\n"
+ "ProductLanguage\t1033\n"
+ "ProductName\tMSITEST\n"
+ "ProductVersion\t1.1.1\n"
+ "PROMPTROLLBACKCOST\tP\n"
+ "Setup\tSetup\n"
+ "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
+ "AdminProperties\tPOSTADMIN\n"
+ "ROOTDRIVE\tC:\\\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"
+ "Var5\t-MSITESTVAR5\t\tOne\n"
+ "Var6\tMSITESTVAR6\t\tOne\n"
+ "Var7\t!-MSITESTVAR7\t\tOne\n"
+ "Var8\t!-*MSITESTVAR8\t\tOne\n"
+ "Var9\t=-MSITESTVAR9\t\tOne\n"
+ "Var10\t=MSITESTVAR10\t\tOne\n"
+ "Var11\t+-MSITESTVAR11\t[~];1\tOne\n"
+ "Var12\t+-MSITESTVAR11\t[~];2\tOne\n"
+ "Var13\t+-MSITESTVAR12\t[~];1\tOne\n"
+ "Var14\t=MSITESTVAR13\t[~];1\tOne\n"
+ "Var15\t=MSITESTVAR13\t[~];2\tOne\n"
+ "Var16\t=MSITESTVAR14\t;1;\tOne\n"
+ "Var17\t=MSITESTVAR15\t;;1;;\tOne\n"
+ "Var18\t=MSITESTVAR16\t 1 \tOne\n"
+ "Var19\t+-MSITESTVAR17\t1\tOne\n"
+ "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n"
+ "Var21\t+-MSITESTVAR18\t1\tOne\n"
+ "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n"
+ "Var23\t+-MSITESTVAR19\t1\tOne\n"
+ "Var24\t+-MSITESTVAR19\t[~]2\tOne\n"
+ "Var25\t+-MSITESTVAR20\t1\tOne\n"
+ "Var26\t+-MSITESTVAR20\t2[~]\tOne\n";
+
+/* Expected results, starting from MSITESTVAR11 onwards */
+static const CHAR *environment_dat_results[] = {"1;2", /*MSITESTVAR11*/
+ "1", /*MSITESTVAR12*/
+ "1;2", /*MSITESTVAR13*/
+ ";1;", /*MSITESTVAR14*/
+ ";;1;;", /*MSITESTVAR15*/
+ " 1 ", /*MSITESTVAR16*/
+ ";;2;;1", /*MSITESTVAR17*/
+ "1;;2;;", /*MSITESTVAR18*/
+ "1", /*MSITESTVAR19*/
+ "1", /*MSITESTVAR20*/
+ NULL};
+
+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"
+ "DefaultUIFont\tDlgFont8\n"
+ "HASUIRUN\t0\n"
+ "INSTALLLEVEL\t3\n"
+ "InstallMode\tTypical\n"
+ "Manufacturer\tWine\n"
+ "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
+ "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
+ "ProductID\tnone\n"
+ "ProductLanguage\t1033\n"
+ "ProductName\tMSITEST\n"
+ "ProductVersion\t1.1.1\n"
+ "PROMPTROLLBACKCOST\tP\n"
+ "Setup\tSetup\n"
+ "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
+ "AdminProperties\tPOSTADMIN\n"
+ "ROOTDRIVE\tC:\\\n"
+ "SERVNAME\tTestService\n"
+ "SERVDISP\tTestServiceDisp\n"
+ "RemovePreviousVersions\t1\n";
+
+static const CHAR up2_property_dat[] = "Property\tValue\n"
+ "s72\tl0\n"
+ "Property\tProperty\n"
+ "DefaultUIFont\tDlgFont8\n"
+ "HASUIRUN\t0\n"
+ "INSTALLLEVEL\t3\n"
+ "InstallMode\tTypical\n"
+ "Manufacturer\tWine\n"
+ "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
+ "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
+ "ProductID\tnone\n"
+ "ProductLanguage\t1033\n"
+ "ProductName\tMSITEST\n"
+ "ProductVersion\t1.1.2\n"
+ "PROMPTROLLBACKCOST\tP\n"
+ "Setup\tSetup\n"
+ "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
+ "AdminProperties\tPOSTADMIN\n"
+ "ROOTDRIVE\tC:\\\n"
+ "SERVNAME\tTestService\n"
+ "SERVDISP\tTestServiceDisp\n";
+
+static const CHAR up3_property_dat[] = "Property\tValue\n"
+ "s72\tl0\n"
+ "Property\tProperty\n"
+ "DefaultUIFont\tDlgFont8\n"
+ "HASUIRUN\t0\n"
+ "INSTALLLEVEL\t3\n"
+ "InstallMode\tTypical\n"
+ "Manufacturer\tWine\n"
+ "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
+ "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
+ "ProductID\tnone\n"
+ "ProductLanguage\t1033\n"
+ "ProductName\tMSITEST\n"
+ "ProductVersion\t1.1.2\n"
+ "PROMPTROLLBACKCOST\tP\n"
+ "Setup\tSetup\n"
+ "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
+ "AdminProperties\tPOSTADMIN\n"
+ "ROOTDRIVE\tC:\\\n"
+ "SERVNAME\tTestService\n"
+ "SERVDISP\tTestServiceDisp\n"
+ "RemovePreviousVersions\t1\n";
+
static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
"s72\ti2\tl255\tL255\tL0\ts72\n"
"Registry\tRegistry\n"
"ServiceControl\tServiceControl\n"
"ServiceControl\tTestService\t8\t\t0\tservice_comp";
+static const CHAR sss_service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
+ "s72\tl255\ti2\tL255\tI2\ts72\n"
+ "ServiceControl\tServiceControl\n"
+ "ServiceControl\tSpooler\t1\t\t0\tservice_comp";
+
+static const CHAR sss_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "CostFinalize\t\t1000\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "ResolveSource\t\t950\n"
+ "MoveFiles\t\t1700\n"
+ "InstallFiles\t\t4000\n"
+ "DuplicateFiles\t\t4500\n"
+ "WriteEnvironmentStrings\t\t4550\n"
+ "CreateShortcuts\t\t4600\n"
+ "StartServices\t\t5000\n"
+ "DeleteServices\t\t5500\n"
+ "InstallFinalize\t\t6600\n"
+ "InstallInitialize\t\t1500\n"
+ "InstallValidate\t\t1400\n"
+ "LaunchConditions\t\t100\n";
+
/* tables for test_continuouscabs */
static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
"s72\tS38\ts72\ti2\tS255\tS72\n"
"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"
"s72\ts72\ts72\tS255\tS72\n"
"DuplicateFile\tFileKey\n"
"maximus\tmaximus\tmaximus\taugustus\t\n"
- "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n";
+ "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n"
+ "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n";
static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
"s72\tS38\ts72\ti2\tS255\tS72\n"
"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";
+
+static const CHAR aup_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"
+ "TestAllUsersProp\tALLUSERS AND NOT REMOVE\t50\n";
+
+static const CHAR aup2_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"
+ "TestAllUsersProp\tALLUSERS=2 AND NOT REMOVE\t50\n";
+
+static const CHAR aup3_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"
+ "TestAllUsersProp\tALLUSERS=1 AND NOT REMOVE\t50\n";
+
+static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
+ "s72\ti2\tS64\tS0\tS255\n"
+ "CustomAction\tAction\n"
+ "TestAllUsersProp\t19\t\tTest failed\t\n";
+
+static const CHAR cf_create_folders_dat[] = "Directory_\tComponent_\n"
+ "s72\ts72\n"
+ "CreateFolder\tDirectory_\tComponent_\n"
+ "FIRSTDIR\tOne\n";
+
+static const CHAR cf_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"
+ "CreateFolders\t\t3700\n"
+ "InstallExecute\t\t3800\n"
+ "TestCreateFolders\t\t3900\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";
+
+static const CHAR cf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
+ "s72\ti2\tS64\tS0\tS255\n"
+ "CustomAction\tAction\n"
+ "TestCreateFolders\t19\t\tHalts installation\t\n";
+
+static const CHAR rf_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"
+ "CreateFolders\t\t3600\n"
+ "RemoveFolders\t\t3700\n"
+ "InstallExecute\t\t3800\n"
+ "TestCreateFolders\t\t3900\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";
+
+
+static const CHAR sr_selfreg_dat[] = "File_\tCost\n"
+ "s72\tI2\n"
+ "SelfReg\tFile_\n"
+ "one.txt\t1\n";
+
+static const CHAR sr_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "CostFinalize\t\t1000\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "ResolveSource\t\t950\n"
+ "MoveFiles\t\t1700\n"
+ "SelfUnregModules\t\t3900\n"
+ "InstallFiles\t\t4000\n"
+ "DuplicateFiles\t\t4500\n"
+ "WriteEnvironmentStrings\t\t4550\n"
+ "CreateShortcuts\t\t4600\n"
+ "InstallFinalize\t\t6600\n"
+ "InstallInitialize\t\t1500\n"
+ "InstallValidate\t\t1400\n"
+ "LaunchConditions\t\t100\n";
+
+static const CHAR font_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
+ "i2\ti4\tL64\tS255\tS32\tS72\n"
+ "Media\tDiskId\n"
+ "1\t3\t\t\tDISK1\t\n";
+
+static const CHAR font_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+ "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+ "File\tFile\n"
+ "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n";
+
+static const CHAR font_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
+ "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
+ "Feature\tFeature\n"
+ "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n";
+
+static const CHAR font_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n";
+
+static const CHAR font_feature_comp_dat[] = "Feature_\tComponent_\n"
+ "s38\ts72\n"
+ "FeatureComponents\tFeature_\tComponent_\n"
+ "fonts\tfonts\n";
+
+static const CHAR font_dat[] = "File_\tFontTitle\n"
+ "s72\tS128\n"
+ "Font\tFile_\n"
+ "font.ttf\tmsi test font\n";
+
+static const CHAR font_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "ValidateProductID\t\t700\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "ProcessComponents\t\t1600\n"
+ "UnpublishFeatures\t\t1800\n"
+ "RemoveFiles\t\t3500\n"
+ "InstallFiles\t\t4000\n"
+ "RegisterFonts\t\t4100\n"
+ "UnregisterFonts\t\t4200\n"
+ "RegisterUser\t\t6000\n"
+ "RegisterProduct\t\t6100\n"
+ "PublishFeatures\t\t6300\n"
+ "PublishProduct\t\t6400\n"
+ "InstallFinalize\t\t6600";
+
+static const CHAR vp_property_dat[] = "Property\tValue\n"
+ "s72\tl0\n"
+ "Property\tProperty\n"
+ "HASUIRUN\t0\n"
+ "INSTALLLEVEL\t3\n"
+ "InstallMode\tTypical\n"
+ "Manufacturer\tWine\n"
+ "PIDTemplate\t###-#######\n"
+ "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
+ "ProductLanguage\t1033\n"
+ "ProductName\tMSITEST\n"
+ "ProductVersion\t1.1.1\n"
+ "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n";
+
+static const CHAR vp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
+ "s72\ti2\tS64\tS0\tS255\n"
+ "CustomAction\tAction\n"
+ "SetProductID1\t51\tProductID\t1\t\n"
+ "SetProductID2\t51\tProductID\t2\t\n"
+ "TestProductID1\t19\t\t\tHalts installation\n"
+ "TestProductID2\t19\t\t\tHalts installation\n";
+
+static const CHAR vp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "LaunchConditions\t\t100\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "SetProductID1\tSET_PRODUCT_ID=1\t3000\n"
+ "SetProductID2\tSET_PRODUCT_ID=2\t3100\n"
+ "ValidateProductID\t\t3200\n"
+ "InstallExecute\t\t3300\n"
+ "TestProductID1\tProductID=1\t3400\n"
+ "TestProductID2\tProductID=\"123-1234567\"\t3500\n"
+ "InstallFiles\t\t4000\n"
+ "InstallFinalize\t\t6000\n";
+
+static const CHAR odbc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+ "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+ "File\tFile\n"
+ "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n"
+ "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n"
+ "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n"
+ "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n"
+ "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n";
+
+static const CHAR odbc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
+ "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
+ "Feature\tFeature\n"
+ "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n";
+
+static const CHAR odbc_feature_comp_dat[] = "Feature_\tComponent_\n"
+ "s38\ts72\n"
+ "FeatureComponents\tFeature_\tComponent_\n"
+ "odbc\todbc\n";
+
+static const CHAR odbc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n";
+
+static const CHAR odbc_driver_dat[] = "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n"
+ "s72\ts72\ts255\ts72\tS72\n"
+ "ODBCDriver\tDriver\n"
+ "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n"
+ "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n";
+
+static const CHAR odbc_translator_dat[] = "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n"
+ "s72\ts72\ts255\ts72\tS72\n"
+ "ODBCTranslator\tTranslator\n"
+ "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n"
+ "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n";
+
+static const CHAR odbc_datasource_dat[] = "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n"
+ "s72\ts72\ts255\ts255\ti2\n"
+ "ODBCDataSource\tDataSource\n"
+ "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n";
+
+static const CHAR odbc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "LaunchConditions\t\t100\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "InstallODBC\t\t3000\n"
+ "RemoveODBC\t\t3100\n"
+ "InstallFiles\t\t4000\n"
+ "InstallFinalize\t\t6000\n";
+
+static const CHAR odbc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
+ "i2\ti4\tL64\tS255\tS32\tS72\n"
+ "Media\tDiskId\n"
+ "1\t5\t\t\tDISK1\t\n";
+
+static const CHAR tl_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+ "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+ "File\tFile\n"
+ "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
+
+static const CHAR tl_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
+ "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
+ "Feature\tFeature\n"
+ "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
+
+static const CHAR tl_feature_comp_dat[] = "Feature_\tComponent_\n"
+ "s38\ts72\n"
+ "FeatureComponents\tFeature_\tComponent_\n"
+ "typelib\ttypelib\n";
+
+static const CHAR tl_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
+
+static const CHAR tl_typelib_dat[] = "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
+ "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
+ "TypeLib\tLibID\tLanguage\tComponent_\n"
+ "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
+
+static const CHAR tl_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "LaunchConditions\t\t100\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "ProcessComponents\t\t1600\n"
+ "RemoveFiles\t\t1700\n"
+ "InstallFiles\t\t2000\n"
+ "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
+ "UnregisterTypeLibraries\t\t3100\n"
+ "RegisterProduct\t\t5100\n"
+ "PublishFeatures\t\t5200\n"
+ "PublishProduct\t\t5300\n"
+ "InstallFinalize\t\t6000\n";
+
+static const CHAR crs_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+ "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+ "File\tFile\n"
+ "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n";
+
+static const CHAR crs_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
+ "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
+ "Feature\tFeature\n"
+ "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n";
+
+static const CHAR crs_feature_comp_dat[] = "Feature_\tComponent_\n"
+ "s38\ts72\n"
+ "FeatureComponents\tFeature_\tComponent_\n"
+ "shortcut\tshortcut\n";
+
+static const CHAR crs_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n";
+
+static const CHAR crs_shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
+ "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n"
+ "Shortcut\tShortcut\n"
+ "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n";
+
+static const CHAR crs_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "LaunchConditions\t\t100\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "ProcessComponents\t\t1600\n"
+ "RemoveFiles\t\t1700\n"
+ "InstallFiles\t\t2000\n"
+ "RemoveShortcuts\t\t3000\n"
+ "CreateShortcuts\t\t3100\n"
+ "RegisterProduct\t\t5000\n"
+ "PublishFeatures\t\t5100\n"
+ "PublishProduct\t\t5200\n"
+ "InstallFinalize\t\t6000\n";
+
+static const CHAR pub_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+ "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+ "File\tFile\n"
+ "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n";
+
+static const CHAR pub_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
+ "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
+ "Feature\tFeature\n"
+ "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n";
+
+static const CHAR pub_feature_comp_dat[] = "Feature_\tComponent_\n"
+ "s38\ts72\n"
+ "FeatureComponents\tFeature_\tComponent_\n"
+ "publish\tpublish\n";
+
+static const CHAR pub_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n";
+
+static const CHAR pub_publish_component_dat[] = "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n"
+ "s38\ts255\ts72\tL255\ts38\n"
+ "PublishComponent\tComponentId\tQualifier\tComponent_\n"
+ "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n";
+
+static const CHAR pub_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "LaunchConditions\t\t100\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "ProcessComponents\t\t1600\n"
+ "RemoveFiles\t\t1700\n"
+ "InstallFiles\t\t2000\n"
+ "PublishComponents\t\t3000\n"
+ "UnpublishComponents\t\t3100\n"
+ "RegisterProduct\t\t5000\n"
+ "PublishFeatures\t\t5100\n"
+ "PublishProduct\t\t5200\n"
+ "InstallFinalize\t\t6000\n";
+
typedef struct _msi_table
{
const CHAR *filename;
ADD_TABLE(service_control)
};
-static const msi_table cc_tables[] =
+static const msi_table sc_tables[] =
{
- ADD_TABLE(cc_component),
+ ADD_TABLE(component),
ADD_TABLE(directory),
- ADD_TABLE(cc_feature),
- ADD_TABLE(cc_feature_comp),
- ADD_TABLE(cc_file),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
ADD_TABLE(install_exec_seq),
- ADD_TABLE(cc_media),
+ ADD_TABLE(media),
ADD_TABLE(property),
+ ADD_TABLE(shortcut)
};
-static const msi_table cc2_tables[] =
+static const msi_table ps_tables[] =
{
- ADD_TABLE(cc2_component),
+ ADD_TABLE(component),
ADD_TABLE(directory),
- ADD_TABLE(cc_feature),
- ADD_TABLE(cc_feature_comp),
- ADD_TABLE(cc2_file),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
ADD_TABLE(install_exec_seq),
- ADD_TABLE(cc_media),
+ ADD_TABLE(media),
ADD_TABLE(property),
+ ADD_TABLE(condition)
};
-static const msi_table co_tables[] =
+static const msi_table env_tables[] =
{
- ADD_TABLE(cc_component),
+ ADD_TABLE(component),
ADD_TABLE(directory),
- ADD_TABLE(cc_feature),
- ADD_TABLE(cc_feature_comp),
- ADD_TABLE(co_file),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
ADD_TABLE(install_exec_seq),
- ADD_TABLE(co_media),
+ ADD_TABLE(media),
ADD_TABLE(property),
+ ADD_TABLE(environment)
};
-static const msi_table co2_tables[] =
+static const msi_table up_tables[] =
{
- ADD_TABLE(cc_component),
+ ADD_TABLE(component),
ADD_TABLE(directory),
- ADD_TABLE(cc_feature),
- ADD_TABLE(cc_feature_comp),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(up_property),
+ ADD_TABLE(registry),
+ ADD_TABLE(service_install),
+ ADD_TABLE(service_control)
+};
+
+static const msi_table up2_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(up2_property),
+ ADD_TABLE(registry),
+ ADD_TABLE(service_install),
+ ADD_TABLE(service_control)
+};
+
+static const msi_table up3_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(up3_property),
+ ADD_TABLE(registry),
+ ADD_TABLE(service_install),
+ ADD_TABLE(service_control)
+};
+
+static const msi_table up4_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(pp_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(property),
+ ADD_TABLE(registry),
+ ADD_TABLE(service_install),
+ ADD_TABLE(service_control)
+};
+
+static const msi_table up5_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(pp_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(up_property),
+ ADD_TABLE(registry),
+ ADD_TABLE(service_install),
+ ADD_TABLE(service_control)
+};
+
+static const msi_table up6_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(pp_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(up2_property),
+ ADD_TABLE(registry),
+ ADD_TABLE(service_install),
+ ADD_TABLE(service_control)
+};
+
+static const msi_table up7_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(pp_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(up3_property),
+ ADD_TABLE(registry),
+ ADD_TABLE(service_install),
+ ADD_TABLE(service_control)
+};
+
+static const msi_table cc_tables[] =
+{
+ ADD_TABLE(cc_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(cc_feature),
+ ADD_TABLE(cc_feature_comp),
+ ADD_TABLE(cc_file),
+ ADD_TABLE(install_exec_seq),
+ ADD_TABLE(cc_media),
+ ADD_TABLE(property),
+};
+
+static const msi_table cc2_tables[] =
+{
+ ADD_TABLE(cc2_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(cc_feature),
+ ADD_TABLE(cc_feature_comp),
+ ADD_TABLE(cc2_file),
+ ADD_TABLE(install_exec_seq),
+ ADD_TABLE(cc_media),
+ ADD_TABLE(property),
+};
+
+static const msi_table co_tables[] =
+{
+ ADD_TABLE(cc_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(cc_feature),
+ ADD_TABLE(cc_feature_comp),
+ ADD_TABLE(co_file),
+ ADD_TABLE(install_exec_seq),
+ ADD_TABLE(co_media),
+ ADD_TABLE(property),
+};
+
+static const msi_table co2_tables[] =
+{
+ ADD_TABLE(cc_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(cc_feature),
+ ADD_TABLE(cc_feature_comp),
ADD_TABLE(cc_file),
ADD_TABLE(install_exec_seq),
ADD_TABLE(co2_media),
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),
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),
ADD_TABLE(property)
};
-/* cabinet definitions */
-
-/* make the max size large so there is only one cab file */
-#define MEDIA_SIZE 0x7FFFFFFF
-#define FOLDER_THRESHOLD 900000
+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)
+};
-/* the FCI callbacks */
+static const msi_table aup_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(aup_install_exec_seq),
+ ADD_TABLE(aup_custom_action),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
-static void * CDECL mem_alloc(ULONG cb)
+static const msi_table aup2_tables[] =
{
- return HeapAlloc(GetProcessHeap(), 0, cb);
-}
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(aup2_install_exec_seq),
+ ADD_TABLE(aup_custom_action),
+ ADD_TABLE(media),
+ ADD_TABLE(aup_property)
+};
-static void CDECL mem_free(void *memory)
+static const msi_table aup3_tables[] =
{
- HeapFree(GetProcessHeap(), 0, memory);
-}
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(aup2_install_exec_seq),
+ ADD_TABLE(aup_custom_action),
+ ADD_TABLE(media),
+ ADD_TABLE(aup2_property)
+};
-static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
+static const msi_table aup4_tables[] =
{
- sprintf(pccab->szCab, pv, pccab->iCab);
- return TRUE;
-}
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(aup3_install_exec_seq),
+ ADD_TABLE(aup_custom_action),
+ ADD_TABLE(media),
+ ADD_TABLE(aup2_property)
+};
-static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
+static const msi_table fiu_tables[] =
{
- return 0;
-}
+ 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 int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
- BOOL fContinuation, void *pv)
+static const msi_table fiuc_tables[] =
{
- return 0;
-}
+ 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),
+};
-static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
+static const msi_table cf_tables[] =
{
- HANDLE handle;
- DWORD dwAccess = 0;
- DWORD dwShareMode = 0;
- DWORD dwCreateDisposition = OPEN_EXISTING;
-
- dwAccess = GENERIC_READ | GENERIC_WRITE;
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(cf_create_folders),
+ ADD_TABLE(cf_install_exec_seq),
+ ADD_TABLE(cf_custom_action),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+static const msi_table rf_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(cf_create_folders),
+ ADD_TABLE(rf_install_exec_seq),
+ ADD_TABLE(cf_custom_action),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+static const msi_table sss_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(sss_install_exec_seq),
+ ADD_TABLE(sss_service_control),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+static const msi_table sds_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(sss_install_exec_seq),
+ ADD_TABLE(service_control),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+static const msi_table sr_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(sr_selfreg),
+ ADD_TABLE(sr_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+static const msi_table font_tables[] =
+{
+ ADD_TABLE(font_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(font_feature),
+ ADD_TABLE(font_feature_comp),
+ ADD_TABLE(font_file),
+ ADD_TABLE(font),
+ ADD_TABLE(font_install_exec_seq),
+ ADD_TABLE(font_media),
+ ADD_TABLE(property)
+};
+
+static const msi_table vp_tables[] =
+{
+ ADD_TABLE(component),
+ ADD_TABLE(directory),
+ ADD_TABLE(feature),
+ ADD_TABLE(feature_comp),
+ ADD_TABLE(file),
+ ADD_TABLE(vp_custom_action),
+ ADD_TABLE(vp_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(vp_property)
+};
+
+static const msi_table odbc_tables[] =
+{
+ ADD_TABLE(odbc_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(odbc_feature),
+ ADD_TABLE(odbc_feature_comp),
+ ADD_TABLE(odbc_file),
+ ADD_TABLE(odbc_driver),
+ ADD_TABLE(odbc_translator),
+ ADD_TABLE(odbc_datasource),
+ ADD_TABLE(odbc_install_exec_seq),
+ ADD_TABLE(odbc_media),
+ ADD_TABLE(property)
+};
+
+static const msi_table tl_tables[] =
+{
+ ADD_TABLE(tl_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(tl_feature),
+ ADD_TABLE(tl_feature_comp),
+ ADD_TABLE(tl_file),
+ ADD_TABLE(tl_typelib),
+ ADD_TABLE(tl_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+static const msi_table crs_tables[] =
+{
+ ADD_TABLE(crs_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(crs_feature),
+ ADD_TABLE(crs_feature_comp),
+ ADD_TABLE(crs_file),
+ ADD_TABLE(crs_shortcut),
+ ADD_TABLE(crs_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+static const msi_table pub_tables[] =
+{
+ ADD_TABLE(directory),
+ ADD_TABLE(pub_component),
+ ADD_TABLE(pub_feature),
+ ADD_TABLE(pub_feature_comp),
+ ADD_TABLE(pub_file),
+ ADD_TABLE(pub_publish_component),
+ ADD_TABLE(pub_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
+/* cabinet definitions */
+
+/* make the max size large so there is only one cab file */
+#define MEDIA_SIZE 0x7FFFFFFF
+#define FOLDER_THRESHOLD 900000
+
+/* the FCI callbacks */
+
+static void * CDECL mem_alloc(ULONG cb)
+{
+ return HeapAlloc(GetProcessHeap(), 0, cb);
+}
+
+static void CDECL mem_free(void *memory)
+{
+ HeapFree(GetProcessHeap(), 0, memory);
+}
+
+static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
+{
+ sprintf(pccab->szCab, pv, pccab->iCab);
+ return TRUE;
+}
+
+static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
+{
+ return 0;
+}
+
+static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
+ BOOL fContinuation, void *pv)
+{
+ return 0;
+}
+
+static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
+{
+ HANDLE handle;
+ DWORD dwAccess = 0;
+ DWORD dwShareMode = 0;
+ DWORD dwCreateDisposition = OPEN_EXISTING;
+
+ dwAccess = GENERIC_READ | GENERIC_WRITE;
/* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
trace("GetProcAddress(%s) failed\n", #func);
GET_PROC(hmsi, MsiQueryComponentStateA);
+ GET_PROC(hmsi, MsiSetExternalUIRecord);
GET_PROC(hmsi, MsiSourceListEnumSourcesA);
GET_PROC(hmsi, MsiSourceListGetInfoA);
create_test_files();
create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
+ /* install, don't publish */
r = MsiInstallProductA(msifile, NULL);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
- delete_test_files();
-}
-
-static void test_MsiSetComponentState(void)
-{
- INSTALLSTATE installed, action;
- MSIHANDLE package;
- char path[MAX_PATH];
- UINT r;
+ /* not published, reinstall */
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
+ 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
- CoInitialize(NULL);
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
- lstrcpy(path, CURR_DIR);
- lstrcat(path, "\\");
- lstrcat(path, msifile);
+ create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table));
- r = MsiOpenPackage(path, &package);
+ /* not published, RemovePreviousVersions set */
+ r = MsiInstallProductA(msifile, NULL);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- r = MsiDoAction(package, "CostInitialize");
- 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
- r = MsiDoAction(package, "FileCost");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
- r = MsiDoAction(package, "CostFinalize");
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table));
- r = MsiGetComponentState(package, "dangler", &installed, &action);
+ /* not published, version number bumped */
+ r = MsiInstallProductA(msifile, NULL);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
- ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
- r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
- 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
- MsiCloseHandle(package);
- CoUninitialize();
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
- DeleteFileA(msifile);
-}
+ create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table));
-static void test_packagecoltypes(void)
-{
- MSIHANDLE hdb, view, rec;
- char path[MAX_PATH];
- LPCSTR query;
- UINT r, count;
+ /* not published, RemovePreviousVersions set and version number bumped */
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
+ 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
- CoInitialize(NULL);
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+ RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
- lstrcpy(path, CURR_DIR);
- lstrcat(path, "\\");
- lstrcat(path, msifile);
+ create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
- r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
+ /* install, publish product */
+ r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- query = "SELECT * FROM `Media`";
- r = MsiDatabaseOpenView( hdb, query, &view );
- ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
+ 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
- r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
- count = MsiRecordGetFieldCount( rec );
- ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
+
+ /* published, reinstall */
+ 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table));
+
+ /* published product, RemovePreviousVersions set */
+ 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table));
+
+ /* published product, version number bumped */
+ 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table));
+
+ /* published product, RemovePreviousVersions set and version number bumped */
+ 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\\one.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+ res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ delete_test_files();
+}
+
+static void test_MsiSetComponentState(void)
+{
+ INSTALLSTATE installed, action;
+ MSIHANDLE package;
+ char path[MAX_PATH];
+ UINT r;
+
+ create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
+
+ CoInitialize(NULL);
+
+ lstrcpy(path, CURR_DIR);
+ lstrcat(path, "\\");
+ lstrcat(path, msifile);
+
+ r = MsiOpenPackage(path, &package);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiDoAction(package, "CostInitialize");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiDoAction(package, "FileCost");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiDoAction(package, "CostFinalize");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiGetComponentState(package, "dangler", &installed, &action);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
+ ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
+
+ r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ MsiCloseHandle(package);
+ CoUninitialize();
+
+ DeleteFileA(msifile);
+}
+
+static void test_packagecoltypes(void)
+{
+ MSIHANDLE hdb, view, rec;
+ char path[MAX_PATH];
+ LPCSTR query;
+ UINT r, count;
+
+ create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
+
+ CoInitialize(NULL);
+
+ lstrcpy(path, CURR_DIR);
+ lstrcat(path, "\\");
+ lstrcat(path, msifile);
+
+ r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ query = "SELECT * FROM `Media`";
+ r = MsiDatabaseOpenView( hdb, query, &view );
+ ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
+
+ r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
+ count = MsiRecordGetFieldCount( rec );
+ ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
ok(count == 6, "Expected 6, got %d\n", count);
ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
DeleteFile(msifile);
}
-static void test_setdirproperty(void)
+static void test_readonlyfile_cab(void)
{
UINT r;
+ DWORD size;
+ HANDLE file;
+ CHAR path[MAX_PATH];
+ CHAR buf[16];
CreateDirectoryA("msitest", NULL);
- create_file("msitest\\maximus", 500);
- create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
+ 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);
- ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
- ok(delete_cf("msitest", FALSE), "File not installed\n");
+
+ 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(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "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 */
- DeleteFile(msifile);
+ delete_cab_files();
DeleteFile("msitest\\maximus");
RemoveDirectory("msitest");
+ DeleteFile(msifile);
}
-static void test_cabisextracted(void)
+static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
{
- UINT r;
-
- CreateDirectoryA("msitest", NULL);
- create_file("msitest\\gaius", 500);
- create_file("maximus", 500);
- create_file("augustus", 500);
- create_file("caesar", 500);
+ WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
+ IStorage *stg;
+ IStream *stm;
+ HRESULT hr;
+ HANDLE handle;
- create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
- create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
- create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
+ 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;
- create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
+ 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;
+ }
- MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+ 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);
+ }
- r = MsiInstallProductA(msifile, NULL);
- ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
- ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
- ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
- ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
- ok(delete_pf("msitest", FALSE), "File not installed\n");
+ IStream_Release(stm);
+ IStorage_Release(stg);
- /* Delete the files in the temp (current) folder */
- delete_cab_files();
- DeleteFile(msifile);
- DeleteFile("maximus");
- DeleteFile("augustus");
- DeleteFile("caesar");
- DeleteFile("msitest\\gaius");
- RemoveDirectory("msitest");
+ return TRUE;
}
-static void test_concurrentinstall(void)
+static void test_lastusedsource(void)
{
+ static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+
UINT r;
- CHAR path[MAX_PATH];
+ char value[MAX_PATH], path[MAX_PATH];
+ DWORD size;
+
+ if (!pMsiSourceListGetInfoA)
+ {
+ win_skip("MsiSourceListGetInfoA is not available\n");
+ return;
+ }
CreateDirectoryA("msitest", NULL);
- CreateDirectoryA("msitest\\msitest", NULL);
- create_file("msitest\\maximus", 500);
- create_file("msitest\\msitest\\augustus", 500);
+ create_file("maximus", 500);
+ create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
+ DeleteFile("maximus");
- create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
+ 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));
- lstrcpyA(path, CURR_DIR);
- lstrcatA(path, "\\msitest\\concurrent.msi");
- create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
- MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+ /* no cabinet file */
- r = MsiInstallProductA(msifile, NULL);
+ 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);
- if (!delete_pf("msitest\\augustus", TRUE))
- trace("concurrent installs not supported\n");
+
+ 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;
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\maximus", 500);
+ create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
+ ok(delete_cf("msitest", FALSE), "File not installed\n");
+
+ /* Delete the files in the temp (current) folder */
+ DeleteFile(msifile);
+ DeleteFile("msitest\\maximus");
+ RemoveDirectory("msitest");
+}
+
+static void test_cabisextracted(void)
+{
+ UINT r;
+
+ CreateDirectoryA("msitest", NULL);
+ create_file("msitest\\gaius", 500);
+ create_file("maximus", 500);
+ create_file("augustus", 500);
+ create_file("caesar", 500);
+
+ create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
+ create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
+ create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
+
+ create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\gaius", 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(msifile);
+ DeleteFile("maximus");
+ DeleteFile("augustus");
+ DeleteFile("caesar");
+ DeleteFile("msitest\\gaius");
+ RemoveDirectory("msitest");
+}
+
+static void test_concurrentinstall(void)
+{
+ UINT r;
+ CHAR path[MAX_PATH];
+
+ CreateDirectoryA("msitest", NULL);
+ CreateDirectoryA("msitest\\msitest", NULL);
+ create_file("msitest\\maximus", 500);
+ create_file("msitest\\msitest\\augustus", 500);
+
+ create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
+
+ lstrcpyA(path, CURR_DIR);
+ lstrcatA(path, "\\msitest\\concurrent.msi");
+ create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ 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\\maximus", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "File not installed\n");
DeleteFile(msifile);
DeleteFile("msitest\\maximus");
RemoveDirectory("msitest");
+ LocalFree(usersid);
}
static void test_publish_processcomponents(void)
DeleteFile(msifile);
DeleteFile("msitest\\maximus");
RemoveDirectory("msitest");
+ LocalFree(usersid);
}
static void test_publish(void)
/* build summary info */
r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
- todo_wine
- {
- ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
- }
+ ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
- }
+ ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
"{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
"{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
"{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
- todo_wine
- {
- ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
- }
+ ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
- todo_wine
- {
- ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
- }
+ 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");
RemoveDirectory("msitest");
}
-START_TEST(install)
+static void test_int_widths( void )
{
- DWORD len;
- char temp_path[MAX_PATH], prev_path[MAX_PATH];
- STATEMGRSTATUS status;
- BOOL ret = FALSE;
-
- init_functionpointers();
+ static const char int0[] = "int0\ni0\nint0\tint0\n1";
+ static const char int1[] = "int1\ni1\nint1\tint1\n1";
+ static const char int2[] = "int2\ni2\nint2\tint2\n1";
+ static const char int3[] = "int3\ni3\nint3\tint3\n1";
+ static const char int4[] = "int4\ni4\nint4\tint4\n1";
+ static const char int5[] = "int5\ni5\nint5\tint5\n1";
+ static const char int8[] = "int8\ni8\nint8\tint8\n1";
- on_win9x = check_win9x();
+ static const struct
+ {
+ const char *data;
+ unsigned int size;
+ UINT ret;
+ }
+ tests[] =
+ {
+ { int0, sizeof(int0) - 1, ERROR_SUCCESS },
+ { int1, sizeof(int1) - 1, ERROR_SUCCESS },
+ { int2, sizeof(int2) - 1, ERROR_SUCCESS },
+ { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
+ { int4, sizeof(int4) - 1, ERROR_SUCCESS },
+ { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
+ { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
+ };
+
+ char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
+ MSIHANDLE db;
+ UINT r, i;
- GetCurrentDirectoryA(MAX_PATH, prev_path);
- GetTempPath(MAX_PATH, temp_path);
- SetCurrentDirectoryA(temp_path);
+ GetTempPathA(MAX_PATH, tmpdir);
+ CreateDirectoryA(tmpdir, NULL);
- lstrcpyA(CURR_DIR, temp_path);
- len = lstrlenA(CURR_DIR);
+ strcpy(msitable, tmpdir);
+ strcat(msitable, "\\msitable.idt");
- if(len && (CURR_DIR[len - 1] == '\\'))
- CURR_DIR[len - 1] = 0;
+ strcpy(msidb, tmpdir);
+ strcat(msidb, "\\msitest.msi");
- get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
+ r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
- /* Create a restore point ourselves so we circumvent the multitude of restore points
- * that would have been created by all the installation and removal tests.
- */
- if (pSRSetRestorePointA)
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
{
- memset(&status, 0, sizeof(status));
- ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
+ write_file(msitable, tests[i].data, tests[i].size);
+
+ r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
+ ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
+
+ r = MsiDatabaseCommit(db);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+ DeleteFileA(msitable);
}
- /* Create only one log file and don't append. We have to pass something
- * for the log mode for this to work.
- */
- MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, "msitest.log", 0);
+ MsiCloseHandle(db);
+ DeleteFileA(msidb);
+ RemoveDirectoryA(tmpdir);
+}
- test_MsiInstallProduct();
- test_MsiSetComponentState();
- test_packagecoltypes();
- test_continuouscabs();
- test_caborder();
- test_mixedmedia();
- test_samesequence();
- test_uiLevelFlags();
- test_readonlyfile();
- test_setdirproperty();
- test_cabisextracted();
- test_concurrentinstall();
- test_setpropertyfolder();
- test_publish_registerproduct();
- test_publish_publishproduct();
- test_publish_publishfeatures();
- test_publish_registeruser();
- test_publish_processcomponents();
- test_publish();
- test_publishsourcelist();
- test_transformprop();
- test_currentworkingdir();
- test_admin();
- test_adminprops();
- test_removefiles();
- test_movefiles();
- test_missingcab();
- test_duplicatefiles();
- test_writeregistryvalues();
- test_sourcefolder();
- test_customaction51();
- test_installstate();
- test_sourcepath();
- test_MsiConfigureProductEx();
- test_missingcomponent();
- test_sourcedirprop();
- test_adminimage();
- test_propcase();
+static void test_shortcut(void)
+{
+ UINT r;
+ HRESULT hr;
+
+ create_test_files();
+ create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
- DeleteFileA("msitest.log");
+ 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];
+ UINT i;
+
+ 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);
+
+ res = RegDeleteValueA(env, "MSITESTVAR5");
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ res = RegDeleteValueA(env, "MSITESTVAR6");
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ res = RegDeleteValueA(env, "MSITESTVAR7");
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ res = RegDeleteValueA(env, "MSITESTVAR8");
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ res = RegDeleteValueA(env, "MSITESTVAR9");
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ res = RegDeleteValueA(env, "MSITESTVAR10");
+ ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+ i = 11;
+ while (environment_dat_results[(i-11)]) {
+ char name[20];
+ sprintf(name, "MSITESTVAR%d", i);
+
+ type = REG_NONE;
+ size = sizeof(buffer);
+ buffer[0] = 0;
+ res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
+ ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
+ ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
+ ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n",
+ i, environment_dat_results[(i-11)], buffer);
+
+ res = RegDeleteValueA(env, name);
+ ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
+ i++;
+ }
+
+
+ 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");
+ ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
+ ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
+ 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 void test_allusers_prop(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ /* ALLUSERS property unset */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ 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");
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ delete_test_files();
+
+ create_test_files();
+ create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ /* ALLUSERS property set to 1 */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ 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");
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ delete_test_files();
+
+ create_test_files();
+ create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ /* ALLUSERS property set to 2 */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ 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");
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ delete_test_files();
+
+ create_test_files();
+ create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
+ r = MsiInstallProductA(msifile, "FULL=1");
+ if (r == ERROR_SUCCESS)
+ {
+ /* Win9x/WinMe */
+ win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n");
+
+ 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();
+ }
+ else
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+}
+
+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, *buf2, *buf2ptr;
+ DWORD size, buf2len = 0;
+ LONG ret;
+ BOOL found = FALSE;
+
+ ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
+ buf = HeapAlloc(GetProcessHeap(), 0, size);
+ buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ buf[0] = 0;
+
+ ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
+ ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
+
+ for (src = buf; *src; src = dst + strlen(dst) + 1)
+ {
+ DWORD flags = MOVEFILE_COPY_ALLOWED;
+
+ dst = src + strlen(src) + 1;
+
+ if (!strstr(src, "msitest"))
+ {
+ lstrcpyA(buf2ptr, src);
+ buf2len += strlen(src) + 1;
+ buf2ptr += strlen(src) + 1;
+ if (*dst)
+ {
+ lstrcpyA(buf2ptr, dst);
+ buf2ptr += strlen(dst) + 1;
+ buf2len += strlen(dst) + 1;
+ }
+ buf2ptr++;
+ buf2len++;
+ continue;
+ }
+
+ found = TRUE;
+
+ 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());
+ }
+
+ ok(found, "Expected a 'msitest' entry\n");
+
+ if (*buf2)
+ {
+ buf2len++;
+ RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len);
+ }
+ else
+ RegDeleteValueA(hkey, rename_ops);
+
+ HeapFree(GetProcessHeap(), 0, buf);
+ HeapFree(GetProcessHeap(), 0, buf2);
+}
+
+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;
+ 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);
+
+ 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;
+ 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);
+
+ 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();
+}
+
+static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
+{
+ return IDOK;
+}
+
+static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
+{
+ return IDOK;
+}
+
+static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
+{
+ return IDOK;
+}
+
+static void test_MsiSetExternalUI(void)
+{
+ INSTALLUI_HANDLERA ret_a;
+ INSTALLUI_HANDLERW ret_w;
+ INSTALLUI_HANDLER_RECORD prev;
+ UINT error;
+
+ ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
+ ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
+
+ ret_a = MsiSetExternalUIA(NULL, 0, NULL);
+ ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
+
+ /* Not present before Installer 3.1 */
+ if (!pMsiSetExternalUIRecord) {
+ win_skip("MsiSetExternalUIRecord is not available\n");
+ return;
+ }
+
+ error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
+ ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
+ ok(prev == NULL, "expected NULL, got %p\n", prev);
+
+ prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
+ error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
+ ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
+ ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
+
+ ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
+ ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
+
+ ret_w = MsiSetExternalUIW(NULL, 0, NULL);
+ ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
+
+ ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
+ ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
+
+ ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
+ ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
+
+ prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
+ error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
+ ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
+ ok(prev == NULL, "expected NULL, got %p\n", prev);
+
+ ret_a = MsiSetExternalUIA(NULL, 0, NULL);
+ ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
+
+ ret_w = MsiSetExternalUIW(NULL, 0, NULL);
+ ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
+
+ prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
+ error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
+ ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
+ ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
+
+ error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
+ ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
+
+ error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
+ ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
+}
+
+static void test_feature_override(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_database(msifile, tables, sizeof(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");
+ ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
+ ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
+ ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+ delete_test_files();
+}
+
+static void test_create_folder(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+
+ ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
+ ok(!delete_pf("msitest", FALSE), "Directory created\n");
+
+ r = MsiInstallProductA(msifile, "LOCAL=Two");
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+
+ ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
+ ok(!delete_pf("msitest", FALSE), "Directory created\n");
+
+ delete_test_files();
+}
+
+static void test_remove_folder(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+
+ ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
+ ok(!delete_pf("msitest", FALSE), "Directory created\n");
+
+ r = MsiInstallProductA(msifile, "LOCAL=Two");
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+
+ ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
+ ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
+ ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
+ ok(!delete_pf("msitest", FALSE), "Directory created\n");
+
+ delete_test_files();
+}
+
+static void test_start_services(void)
+{
+ UINT r;
+ SC_HANDLE scm, service;
+ BOOL ret;
+ DWORD error = ERROR_SUCCESS;
+
+ if (on_win9x)
+ {
+ win_skip("Services are not implemented on Win9x and WinMe\n");
+ return;
+ }
+ scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ ok(scm != NULL, "Failed to open the SC Manager\n");
+ if (!scm) return;
+
+ service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
+ if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
+ {
+ win_skip("The 'Spooler' service does not exist\n");
+ CloseServiceHandle(scm);
+ return;
+ }
+ ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
+ if (!service) {
+ CloseServiceHandle(scm);
+ return;
+ }
+
+ ret = StartService(service, 0, NULL);
+ if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
+ {
+ skip("Terminal service not available, skipping test\n");
+ CloseServiceHandle(service);
+ CloseServiceHandle(scm);
+ return;
+ }
+
+ CloseServiceHandle(service);
+ CloseServiceHandle(scm);
+
+ create_test_files();
+ create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ 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), "Directory not created\n");
+ ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
+ 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", FALSE), "Directory not created\n");
+
+ delete_test_files();
+
+ if (error == ERROR_SUCCESS)
+ {
+ SERVICE_STATUS status;
+
+ scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
+
+ ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
+ ok(ret, "ControlService failed %u\n", GetLastError());
+
+ CloseServiceHandle(service);
+ CloseServiceHandle(scm);
+ }
+}
+
+static void test_delete_services(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ 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), "Directory not created\n");
+ ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
+ 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", FALSE), "Directory not created\n");
+
+ delete_test_files();
+}
+
+static void test_self_registration(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ 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), "Directory not created\n");
+ ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
+ 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", FALSE), "Directory not created\n");
+
+ delete_test_files();
+}
+
+static void test_register_font(void)
+{
+ static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
+ static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
+ LONG ret;
+ HKEY key;
+ UINT r;
+
+ create_test_files();
+ create_file("msitest\\font.ttf", 1000);
+ create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key);
+ if (ret)
+ RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key);
+
+ ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
+ ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
+
+ ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
+ ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
+
+ RegDeleteValueA(key, "msi test font");
+ RegCloseKey(key);
+ delete_test_files();
+}
+
+static void test_validate_product_id(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+
+ r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
+ 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), "Directory not created\n");
+ ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
+ ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
+ ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
+ 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", FALSE), "Directory not created\n");
+
+ delete_test_files();
+}
+
+static void test_install_remove_odbc(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_file("msitest\\ODBCdriver.dll", 1000);
+ create_file("msitest\\ODBCdriver2.dll", 1000);
+ create_file("msitest\\ODBCtranslator.dll", 1000);
+ create_file("msitest\\ODBCtranslator2.dll", 1000);
+ create_file("msitest\\ODBCsetup.dll", 1000);
+ create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ ok(delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not created\n");
+ ok(delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not created\n");
+ ok(delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not created\n");
+ ok(delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not created\n");
+ ok(delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not created\n");
+ ok(delete_pf("msitest", FALSE), "directory not created\n");
+
+ delete_test_files();
+}
+
+static void test_register_typelib(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_file("msitest\\typelib.dll", 1000);
+ create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
+ ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
+ todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
+
+ delete_test_files();
+}
+
+static void test_create_remove_shortcut(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_file("msitest\\target.txt", 1000);
+ create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ ok(pf_exists("msitest\\target.txt"), "file not created\n");
+ ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
+ ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
+ todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
+
+ delete_test_files();
+}
+
+static void test_publish_components(void)
+{
+ static char keypath[] =
+ "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
+
+ UINT r;
+ LONG res;
+ HKEY key;
+
+ create_test_files();
+ create_file("msitest\\english.txt", 1000);
+ create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
+ ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
+
+ res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
+ ok(res == ERROR_SUCCESS, "value not found %d\n", res);
+ RegCloseKey(key);
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
+ ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
+
+ ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
+ todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
+ delete_test_files();
+}
+
+START_TEST(install)
+{
+ DWORD len;
+ char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
+ STATEMGRSTATUS status;
+ BOOL ret = FALSE;
+
+ init_functionpointers();
+
+ on_win9x = check_win9x();
+
+ GetCurrentDirectoryA(MAX_PATH, prev_path);
+ GetTempPath(MAX_PATH, temp_path);
+ SetCurrentDirectoryA(temp_path);
+
+ lstrcpyA(CURR_DIR, temp_path);
+ len = lstrlenA(CURR_DIR);
+
+ if(len && (CURR_DIR[len - 1] == '\\'))
+ CURR_DIR[len - 1] = 0;
+
+ get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
+
+ /* Create a restore point ourselves so we circumvent the multitude of restore points
+ * that would have been created by all the installation and removal tests.
+ */
+ if (pSRSetRestorePointA)
+ {
+ memset(&status, 0, sizeof(status));
+ ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
+ }
+
+ /* Create only one log file and don't append. We have to pass something
+ * for the log mode for this to work. The logfile needs to have an absolute
+ * path otherwise we still end up with some extra logfiles as some tests
+ * change the current directory.
+ */
+ lstrcpyA(log_file, temp_path);
+ lstrcatA(log_file, "\\msitest.log");
+ MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
+
+ test_MsiInstallProduct();
+ test_MsiSetComponentState();
+ test_packagecoltypes();
+ test_continuouscabs();
+ test_caborder();
+ test_mixedmedia();
+ test_samesequence();
+ test_uiLevelFlags();
+ test_readonlyfile();
+ test_readonlyfile_cab();
+ test_setdirproperty();
+ test_cabisextracted();
+ test_concurrentinstall();
+ test_setpropertyfolder();
+ test_publish_registerproduct();
+ test_publish_publishproduct();
+ test_publish_publishfeatures();
+ test_publish_registeruser();
+ test_publish_processcomponents();
+ test_publish();
+ test_publishsourcelist();
+ test_transformprop();
+ test_currentworkingdir();
+ test_admin();
+ test_adminprops();
+ test_removefiles();
+ test_movefiles();
+ test_missingcab();
+ test_duplicatefiles();
+ test_writeregistryvalues();
+ test_sourcefolder();
+ test_customaction51();
+ test_installstate();
+ test_sourcepath();
+ test_MsiConfigureProductEx();
+ test_missingcomponent();
+ test_sourcedirprop();
+ 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();
+ test_MsiSetExternalUI();
+ test_allusers_prop();
+ test_feature_override();
+ test_create_folder();
+ test_remove_folder();
+ test_start_services();
+ test_delete_services();
+ test_self_registration();
+ test_register_font();
+ test_validate_product_id();
+ test_install_remove_odbc();
+ test_register_typelib();
+ test_create_remove_shortcut();
+ test_publish_components();
+
+ DeleteFileA(log_file);
if (pSRSetRestorePointA && ret)
{