wined3d: Default to GLSL. This is safe because we now have proper ps2.0/vs2.0 detection.
[wine] / dlls / msi / tests / install.c
1 /*
2  * Copyright (C) 2006 James Hawkins
3  *
4  * A test program for installing MSI products.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22 #define COBJMACROS
23
24 #include <stdio.h>
25
26 #include <windows.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <msi.h>
30 #include <fci.h>
31 #include <objidl.h>
32
33 #include "wine/test.h"
34
35 static UINT (WINAPI *pMsiQueryComponentStateA)
36     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
37 static UINT (WINAPI *pMsiSourceListGetInfoA)
38     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
39
40 static const char *msifile = "msitest.msi";
41 static const char *msifile2 = "winetest2.msi";
42 static const char *mstfile = "winetest.mst";
43 static CHAR CURR_DIR[MAX_PATH];
44 static CHAR PROG_FILES_DIR[MAX_PATH];
45 static CHAR COMMON_FILES_DIR[MAX_PATH];
46
47 /* msi database data */
48
49 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
50                                     "s72\tS38\ts72\ti2\tS255\tS72\n"
51                                     "Component\tComponent\n"
52                                     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
53                                     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
54                                     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\t\tone.txt\n"
55                                     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
56                                     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
57                                     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
58                                     "component\t\tMSITESTDIR\t0\t1\tfile\n"
59                                     "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
60
61 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
62                                     "s72\tS72\tl255\n"
63                                     "Directory\tDirectory\n"
64                                     "CABOUTDIR\tMSITESTDIR\tcabout\n"
65                                     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
66                                     "FIRSTDIR\tMSITESTDIR\tfirst\n"
67                                     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
68                                     "NEWDIR\tCABOUTDIR\tnew\n"
69                                     "ProgramFilesFolder\tTARGETDIR\t.\n"
70                                     "TARGETDIR\t\tSourceDir";
71
72 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
73                                   "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
74                                   "Feature\tFeature\n"
75                                   "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
76                                   "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
77                                   "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
78                                   "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
79                                   "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
80                                   "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
81                                   "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
82
83 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
84                                        "s38\ts72\n"
85                                        "FeatureComponents\tFeature_\tComponent_\n"
86                                        "Five\tFive\n"
87                                        "Four\tFour\n"
88                                        "One\tOne\n"
89                                        "Three\tThree\n"
90                                        "Two\tTwo\n"
91                                        "feature\tcomponent\n"
92                                        "service_feature\tservice_comp\n";
93
94 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
95                                "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
96                                "File\tFile\n"
97                                "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
98                                "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
99                                "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
100                                "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
101                                "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
102                                "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
103                                "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
104
105 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
106                                            "s72\tS255\tI2\n"
107                                            "InstallExecuteSequence\tAction\n"
108                                            "AllocateRegistrySpace\tNOT Installed\t1550\n"
109                                            "CostFinalize\t\t1000\n"
110                                            "CostInitialize\t\t800\n"
111                                            "FileCost\t\t900\n"
112                                            "InstallFiles\t\t4000\n"
113                                            "InstallServices\t\t5000\n"
114                                            "InstallFinalize\t\t6600\n"
115                                            "InstallInitialize\t\t1500\n"
116                                            "InstallValidate\t\t1400\n"
117                                            "LaunchConditions\t\t100\n"
118                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
119
120 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
121                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
122                                 "Media\tDiskId\n"
123                                 "1\t3\t\t\tDISK1\t\n"
124                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
125
126 static const CHAR property_dat[] = "Property\tValue\n"
127                                    "s72\tl0\n"
128                                    "Property\tProperty\n"
129                                    "DefaultUIFont\tDlgFont8\n"
130                                    "HASUIRUN\t0\n"
131                                    "INSTALLLEVEL\t3\n"
132                                    "InstallMode\tTypical\n"
133                                    "Manufacturer\tWine\n"
134                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
135                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
136                                    "ProductID\tnone\n"
137                                    "ProductLanguage\t1033\n"
138                                    "ProductName\tMSITEST\n"
139                                    "ProductVersion\t1.1.1\n"
140                                    "PROMPTROLLBACKCOST\tP\n"
141                                    "Setup\tSetup\n"
142                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
143                                    "AdminProperties\tPOSTADMIN\n"
144                                    "ROOTDRIVE\tC:\\\n";
145
146 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
147                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
148                                    "Registry\tRegistry\n"
149                                    "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
150                                    "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
151                                    "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
152                                    "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
153
154 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
155                                           "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
156                                           "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
157                                           "ServiceInstall\tServiceInstall\n"
158                                           "TestService\tTestService\tTestService\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
159
160 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
161                                           "s72\tl255\ti2\tL255\tI2\ts72\n"
162                                           "ServiceControl\tServiceControl\n"
163                                           "ServiceControl\tTestService\t8\t\t0\tservice_comp";
164
165 /* tables for test_continuouscabs */
166 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
167                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
168                                        "Component\tComponent\n"
169                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
170                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
171                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
172
173 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
174                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
175                                      "Feature\tFeature\n"
176                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
177
178 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
179                                           "s38\ts72\n"
180                                           "FeatureComponents\tFeature_\tComponent_\n"
181                                           "feature\tmaximus\n"
182                                           "feature\taugustus\n"
183                                           "feature\tcaesar";
184
185 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
186                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
187                                   "File\tFile\n"
188                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
189                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
190                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
191
192 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
193                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
194                                    "Media\tDiskId\n"
195                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
196                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
197                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
198
199 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
200                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
201                                   "File\tFile\n"
202                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
203                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
204                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
205
206 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
207                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
208                                    "Media\tDiskId\n"
209                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
210                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
211                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
212
213 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
214                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
215                                     "Media\tDiskId\n"
216                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
217                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
218                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
219
220 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
221                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
222                                   "File\tFile\n"
223                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
224                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
225                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
226
227 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
228                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
229                                    "Media\tDiskId\n"
230                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
231
232 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
233                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
234                                    "Media\tDiskId\n"
235                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
236                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
237                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
238
239 /* tables for test_uiLevelFlags */
240 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
241                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
242                                        "Component\tComponent\n"
243                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
244                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
245                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
246
247 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
248                                            "s72\tS255\tI2\n"
249                                            "InstallUISequence\tAction\n"
250                                            "SetUIProperty\t\t5\n"
251                                            "ExecuteAction\t\t1100\n";
252
253 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
254                                            "s72\ti2\tS64\tS0\tS255\n"
255                                            "CustomAction\tAction\n"
256                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
257
258 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
259                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
260                                         "Component\tComponent\n"
261                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
262
263 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
264                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
265                                       "Feature\tFeature\n"
266                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
267                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
268
269 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
270                                            "s38\ts72\n"
271                                            "FeatureComponents\tFeature_\tComponent_\n"
272                                            "feature\tmaximus\n"
273                                            "montecristo\tmaximus";
274
275 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
276                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
277                                    "File\tFile\n"
278                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
279
280 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
281                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
282                                     "Media\tDiskId\n"
283                                     "1\t1\t\t\tDISK1\t\n";
284
285 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
286                                                "s72\tS255\tI2\n"
287                                                "InstallExecuteSequence\tAction\n"
288                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
289                                                "CostFinalize\t\t1000\n"
290                                                "CostInitialize\t\t800\n"
291                                                "FileCost\t\t900\n"
292                                                "InstallFiles\t\t4000\n"
293                                                "InstallFinalize\t\t6600\n"
294                                                "InstallInitialize\t\t1500\n"
295                                                "InstallValidate\t\t1400\n"
296                                                "LaunchConditions\t\t100\n"
297                                                "SetDirProperty\t\t950";
298
299 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
300                                             "s72\ti2\tS64\tS0\tS255\n"
301                                             "CustomAction\tAction\n"
302                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
303
304 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
305                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
306                                         "Component\tComponent\n"
307                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
308                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
309                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
310                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
311
312 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
313                                            "s38\ts72\n"
314                                            "FeatureComponents\tFeature_\tComponent_\n"
315                                            "feature\tmaximus\n"
316                                            "feature\taugustus\n"
317                                            "feature\tcaesar\n"
318                                            "feature\tgaius";
319
320 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
321                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
322                                    "File\tFile\n"
323                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
324                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
325                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
326                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
327
328 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
329                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
330                                     "Media\tDiskId\n"
331                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
332                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
333                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
334
335 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
336                                               "s72\tS255\tI2\n"
337                                               "InstallExecuteSequence\tAction\n"
338                                               "CostFinalize\t\t1000\n"
339                                               "CostInitialize\t\t800\n"
340                                               "FileCost\t\t900\n"
341                                               "InstallFiles\t\t4000\n"
342                                               "InstallServices\t\t5000\n"
343                                               "InstallFinalize\t\t6600\n"
344                                               "InstallInitialize\t\t1500\n"
345                                               "RunInstall\t\t1600\n"
346                                               "InstallValidate\t\t1400\n"
347                                               "LaunchConditions\t\t100";
348
349 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
350                                             "s72\ti2\tS64\tS0\tS255\n"
351                                             "CustomAction\tAction\n"
352                                             "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
353
354 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
355                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
356                                        "Component\tComponent\n"
357                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
358
359 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
360                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
361                                         "Component\tComponent\n"
362                                         "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
363
364 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
365                                            "s38\ts72\n"
366                                            "FeatureComponents\tFeature_\tComponent_\n"
367                                            "feature\taugustus";
368
369 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
370                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
371                                    "File\tFile\n"
372                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
373
374 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
375                                             "s72\ti2\tS64\tS0\tS255\n"
376                                             "CustomAction\tAction\n"
377                                             "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
378
379 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
380                                                "s72\tS255\tI2\n"
381                                                "InstallExecuteSequence\tAction\n"
382                                                "CostFinalize\t\t1000\n"
383                                                "CostInitialize\t\t800\n"
384                                                "FileCost\t\t900\n"
385                                                "SetFolderProp\t\t950\n"
386                                                "InstallFiles\t\t4000\n"
387                                                "InstallServices\t\t5000\n"
388                                                "InstallFinalize\t\t6600\n"
389                                                "InstallInitialize\t\t1500\n"
390                                                "InstallValidate\t\t1400\n"
391                                                "LaunchConditions\t\t100";
392
393 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
394                                              "s72\tS255\tI2\n"
395                                              "InstallUISequence\tAction\n"
396                                              "CostInitialize\t\t800\n"
397                                              "FileCost\t\t900\n"
398                                              "CostFinalize\t\t1000\n"
399                                              "ExecuteAction\t\t1100\n";
400
401 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
402                                               "s72\tS255\tI2\n"
403                                               "InstallExecuteSequence\tAction\n"
404                                               "ValidateProductID\t\t700\n"
405                                               "CostInitialize\t\t800\n"
406                                               "FileCost\t\t900\n"
407                                               "CostFinalize\t\t1000\n"
408                                               "InstallValidate\t\t1400\n"
409                                               "InstallInitialize\t\t1500\n"
410                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
411                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
412                                               "RemoveFiles\t\t3500\n"
413                                               "InstallFiles\t\t4000\n"
414                                               "RegisterUser\t\t6000\n"
415                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
416                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
417                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
418                                               "InstallFinalize\t\t6600";
419
420 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
421                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
422                                        "Component\tComponent\n"
423                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
424
425 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
426                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
427                                         "Component\tComponent\n"
428                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
429
430 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
431                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
432                                         "Component\tComponent\n"
433                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
434
435 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
436                                             "s72\ti2\tS64\tS0\tS255\n"
437                                             "CustomAction\tAction\n"
438                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
439
440 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
441                                              "s72\tS255\tI2\n"
442                                              "AdminExecuteSequence\tAction\n"
443                                              "CostFinalize\t\t1000\n"
444                                              "CostInitialize\t\t800\n"
445                                              "FileCost\t\t900\n"
446                                              "SetPOSTADMIN\t\t950\n"
447                                              "InstallFiles\t\t4000\n"
448                                              "InstallFinalize\t\t6600\n"
449                                              "InstallInitialize\t\t1500\n"
450                                              "InstallValidate\t\t1400\n"
451                                              "LaunchConditions\t\t100";
452
453 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
454                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
455                                         "Component\tComponent\n"
456                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718\taugustus\n";
457
458 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
459                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
460                                         "Component\tComponent\n"
461                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
462                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
463                                         "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
464
465 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
466                                            "s38\ts72\n"
467                                            "FeatureComponents\tFeature_\tComponent_\n"
468                                            "feature\thydrogen\n"
469                                            "feature\thelium\n"
470                                            "feature\tlithium";
471
472 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
473                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
474                                    "File\tFile\n"
475                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
476                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
477                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
478
479 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
480                                                "s72\tS255\tI2\n"
481                                                "InstallExecuteSequence\tAction\n"
482                                                "ValidateProductID\t\t700\n"
483                                                "CostInitialize\t\t800\n"
484                                                "FileCost\t\t900\n"
485                                                "CostFinalize\t\t1000\n"
486                                                "InstallValidate\t\t1400\n"
487                                                "InstallInitialize\t\t1500\n"
488                                                "ProcessComponents\t\t1600\n"
489                                                "UnpublishFeatures\t\t1800\n"
490                                                "RemoveFiles\t\t3500\n"
491                                                "InstallFiles\t\t4000\n"
492                                                "RegisterUser\t\t6000\n"
493                                                "RegisterProduct\t\t6100\n"
494                                                "PublishFeatures\t\t6300\n"
495                                                "PublishProduct\t\t6400\n"
496                                                "InstallFinalize\t\t6600";
497
498 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
499                                            "s72\ts72\tS255\ts72\tI2\n"
500                                            "RemoveFile\tFileKey\n"
501                                            "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
502                                            "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
503                                            "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
504                                            "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
505                                            "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
506                                            "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
507                                            "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
508                                            "block\thelium\tblock\tMSITESTDIR\t3\n"
509                                            "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n";
510
511 typedef struct _msi_table
512 {
513     const CHAR *filename;
514     const CHAR *data;
515     int size;
516 } msi_table;
517
518 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
519
520 static const msi_table tables[] =
521 {
522     ADD_TABLE(component),
523     ADD_TABLE(directory),
524     ADD_TABLE(feature),
525     ADD_TABLE(feature_comp),
526     ADD_TABLE(file),
527     ADD_TABLE(install_exec_seq),
528     ADD_TABLE(media),
529     ADD_TABLE(property),
530     ADD_TABLE(registry),
531     ADD_TABLE(service_install),
532     ADD_TABLE(service_control)
533 };
534
535 static const msi_table cc_tables[] =
536 {
537     ADD_TABLE(cc_component),
538     ADD_TABLE(directory),
539     ADD_TABLE(cc_feature),
540     ADD_TABLE(cc_feature_comp),
541     ADD_TABLE(cc_file),
542     ADD_TABLE(install_exec_seq),
543     ADD_TABLE(cc_media),
544     ADD_TABLE(property),
545 };
546
547 static const msi_table co_tables[] =
548 {
549     ADD_TABLE(cc_component),
550     ADD_TABLE(directory),
551     ADD_TABLE(cc_feature),
552     ADD_TABLE(cc_feature_comp),
553     ADD_TABLE(co_file),
554     ADD_TABLE(install_exec_seq),
555     ADD_TABLE(co_media),
556     ADD_TABLE(property),
557 };
558
559 static const msi_table co2_tables[] =
560 {
561     ADD_TABLE(cc_component),
562     ADD_TABLE(directory),
563     ADD_TABLE(cc_feature),
564     ADD_TABLE(cc_feature_comp),
565     ADD_TABLE(cc_file),
566     ADD_TABLE(install_exec_seq),
567     ADD_TABLE(co2_media),
568     ADD_TABLE(property),
569 };
570
571 static const msi_table mm_tables[] =
572 {
573     ADD_TABLE(cc_component),
574     ADD_TABLE(directory),
575     ADD_TABLE(cc_feature),
576     ADD_TABLE(cc_feature_comp),
577     ADD_TABLE(mm_file),
578     ADD_TABLE(install_exec_seq),
579     ADD_TABLE(mm_media),
580     ADD_TABLE(property),
581 };
582
583 static const msi_table ss_tables[] =
584 {
585     ADD_TABLE(cc_component),
586     ADD_TABLE(directory),
587     ADD_TABLE(cc_feature),
588     ADD_TABLE(cc_feature_comp),
589     ADD_TABLE(cc_file),
590     ADD_TABLE(install_exec_seq),
591     ADD_TABLE(ss_media),
592     ADD_TABLE(property),
593 };
594
595 static const msi_table ui_tables[] =
596 {
597     ADD_TABLE(ui_component),
598     ADD_TABLE(directory),
599     ADD_TABLE(cc_feature),
600     ADD_TABLE(cc_feature_comp),
601     ADD_TABLE(cc_file),
602     ADD_TABLE(install_exec_seq),
603     ADD_TABLE(ui_install_ui_seq),
604     ADD_TABLE(ui_custom_action),
605     ADD_TABLE(cc_media),
606     ADD_TABLE(property),
607 };
608
609 static const msi_table rof_tables[] =
610 {
611     ADD_TABLE(rof_component),
612     ADD_TABLE(directory),
613     ADD_TABLE(rof_feature),
614     ADD_TABLE(rof_feature_comp),
615     ADD_TABLE(rof_file),
616     ADD_TABLE(install_exec_seq),
617     ADD_TABLE(rof_media),
618     ADD_TABLE(property),
619 };
620
621 static const msi_table sdp_tables[] =
622 {
623     ADD_TABLE(rof_component),
624     ADD_TABLE(directory),
625     ADD_TABLE(rof_feature),
626     ADD_TABLE(rof_feature_comp),
627     ADD_TABLE(rof_file),
628     ADD_TABLE(sdp_install_exec_seq),
629     ADD_TABLE(sdp_custom_action),
630     ADD_TABLE(rof_media),
631     ADD_TABLE(property),
632 };
633
634 static const msi_table cie_tables[] =
635 {
636     ADD_TABLE(cie_component),
637     ADD_TABLE(directory),
638     ADD_TABLE(cc_feature),
639     ADD_TABLE(cie_feature_comp),
640     ADD_TABLE(cie_file),
641     ADD_TABLE(install_exec_seq),
642     ADD_TABLE(cie_media),
643     ADD_TABLE(property),
644 };
645
646 static const msi_table ci_tables[] =
647 {
648     ADD_TABLE(ci_component),
649     ADD_TABLE(directory),
650     ADD_TABLE(rof_feature),
651     ADD_TABLE(rof_feature_comp),
652     ADD_TABLE(rof_file),
653     ADD_TABLE(ci_install_exec_seq),
654     ADD_TABLE(rof_media),
655     ADD_TABLE(property),
656     ADD_TABLE(ci_custom_action),
657 };
658
659 static const msi_table ci2_tables[] =
660 {
661     ADD_TABLE(ci2_component),
662     ADD_TABLE(directory),
663     ADD_TABLE(rof_feature),
664     ADD_TABLE(ci2_feature_comp),
665     ADD_TABLE(ci2_file),
666     ADD_TABLE(install_exec_seq),
667     ADD_TABLE(rof_media),
668     ADD_TABLE(property),
669 };
670
671 static const msi_table spf_tables[] =
672 {
673     ADD_TABLE(ci_component),
674     ADD_TABLE(directory),
675     ADD_TABLE(rof_feature),
676     ADD_TABLE(rof_feature_comp),
677     ADD_TABLE(rof_file),
678     ADD_TABLE(spf_install_exec_seq),
679     ADD_TABLE(rof_media),
680     ADD_TABLE(property),
681     ADD_TABLE(spf_custom_action),
682     ADD_TABLE(spf_install_ui_seq),
683 };
684
685 static const msi_table pp_tables[] =
686 {
687     ADD_TABLE(ci_component),
688     ADD_TABLE(directory),
689     ADD_TABLE(rof_feature),
690     ADD_TABLE(rof_feature_comp),
691     ADD_TABLE(rof_file),
692     ADD_TABLE(pp_install_exec_seq),
693     ADD_TABLE(rof_media),
694     ADD_TABLE(property),
695 };
696
697 static const msi_table tp_tables[] =
698 {
699     ADD_TABLE(tp_component),
700     ADD_TABLE(directory),
701     ADD_TABLE(rof_feature),
702     ADD_TABLE(ci2_feature_comp),
703     ADD_TABLE(ci2_file),
704     ADD_TABLE(install_exec_seq),
705     ADD_TABLE(rof_media),
706     ADD_TABLE(property),
707 };
708
709 static const msi_table cwd_tables[] =
710 {
711     ADD_TABLE(cwd_component),
712     ADD_TABLE(directory),
713     ADD_TABLE(rof_feature),
714     ADD_TABLE(ci2_feature_comp),
715     ADD_TABLE(ci2_file),
716     ADD_TABLE(install_exec_seq),
717     ADD_TABLE(rof_media),
718     ADD_TABLE(property),
719 };
720
721 static const msi_table adm_tables[] =
722 {
723     ADD_TABLE(adm_component),
724     ADD_TABLE(directory),
725     ADD_TABLE(rof_feature),
726     ADD_TABLE(ci2_feature_comp),
727     ADD_TABLE(ci2_file),
728     ADD_TABLE(install_exec_seq),
729     ADD_TABLE(rof_media),
730     ADD_TABLE(property),
731     ADD_TABLE(adm_custom_action),
732     ADD_TABLE(adm_admin_exec_seq),
733 };
734
735 static const msi_table amp_tables[] =
736 {
737     ADD_TABLE(amp_component),
738     ADD_TABLE(directory),
739     ADD_TABLE(rof_feature),
740     ADD_TABLE(ci2_feature_comp),
741     ADD_TABLE(ci2_file),
742     ADD_TABLE(install_exec_seq),
743     ADD_TABLE(rof_media),
744     ADD_TABLE(property),
745 };
746
747 static const msi_table rem_tables[] =
748 {
749     ADD_TABLE(rem_component),
750     ADD_TABLE(directory),
751     ADD_TABLE(rof_feature),
752     ADD_TABLE(rem_feature_comp),
753     ADD_TABLE(rem_file),
754     ADD_TABLE(rem_install_exec_seq),
755     ADD_TABLE(rof_media),
756     ADD_TABLE(property),
757     ADD_TABLE(rem_remove_files),
758 };
759
760 /* cabinet definitions */
761
762 /* make the max size large so there is only one cab file */
763 #define MEDIA_SIZE          0x7FFFFFFF
764 #define FOLDER_THRESHOLD    900000
765
766 /* the FCI callbacks */
767
768 static void *mem_alloc(ULONG cb)
769 {
770     return HeapAlloc(GetProcessHeap(), 0, cb);
771 }
772
773 static void mem_free(void *memory)
774 {
775     HeapFree(GetProcessHeap(), 0, memory);
776 }
777
778 static BOOL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
779 {
780     sprintf(pccab->szCab, pv, pccab->iCab);
781     return TRUE;
782 }
783
784 static long progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
785 {
786     return 0;
787 }
788
789 static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
790                        BOOL fContinuation, void *pv)
791 {
792     return 0;
793 }
794
795 static INT_PTR fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
796 {
797     HANDLE handle;
798     DWORD dwAccess = 0;
799     DWORD dwShareMode = 0;
800     DWORD dwCreateDisposition = OPEN_EXISTING;
801     
802     dwAccess = GENERIC_READ | GENERIC_WRITE;
803     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
804     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
805
806     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
807         dwCreateDisposition = OPEN_EXISTING;
808     else
809         dwCreateDisposition = CREATE_NEW;
810
811     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
812                          dwCreateDisposition, 0, NULL);
813
814     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
815
816     return (INT_PTR)handle;
817 }
818
819 static UINT fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
820 {
821     HANDLE handle = (HANDLE)hf;
822     DWORD dwRead;
823     BOOL res;
824     
825     res = ReadFile(handle, memory, cb, &dwRead, NULL);
826     ok(res, "Failed to ReadFile\n");
827
828     return dwRead;
829 }
830
831 static UINT fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
832 {
833     HANDLE handle = (HANDLE)hf;
834     DWORD dwWritten;
835     BOOL res;
836
837     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
838     ok(res, "Failed to WriteFile\n");
839
840     return dwWritten;
841 }
842
843 static int fci_close(INT_PTR hf, int *err, void *pv)
844 {
845     HANDLE handle = (HANDLE)hf;
846     ok(CloseHandle(handle), "Failed to CloseHandle\n");
847
848     return 0;
849 }
850
851 static long fci_seek(INT_PTR hf, long dist, int seektype, int *err, void *pv)
852 {
853     HANDLE handle = (HANDLE)hf;
854     DWORD ret;
855     
856     ret = SetFilePointer(handle, dist, NULL, seektype);
857     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
858
859     return ret;
860 }
861
862 static int fci_delete(char *pszFile, int *err, void *pv)
863 {
864     BOOL ret = DeleteFileA(pszFile);
865     ok(ret, "Failed to DeleteFile %s\n", pszFile);
866
867     return 0;
868 }
869
870 static void init_functionpointers(void)
871 {
872     HMODULE hmsi = GetModuleHandleA("msi.dll");
873
874 #define GET_PROC(func) \
875     p ## func = (void*)GetProcAddress(hmsi, #func); \
876     if(!p ## func) \
877       trace("GetProcAddress(%s) failed\n", #func);
878
879     GET_PROC(MsiQueryComponentStateA);
880     GET_PROC(MsiSourceListGetInfoA);
881
882 #undef GET_PROC
883 }
884
885 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
886 {
887     CHAR buffer[0x20];
888     UINT r;
889     DWORD sz;
890
891     sz = sizeof buffer;
892     r = MsiRecordGetString(rec, field, buffer, &sz);
893     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
894 }
895
896 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
897 {
898     LPSTR tempname;
899
900     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
901     GetTempFileNameA(".", "xx", 0, tempname);
902
903     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
904     {
905         lstrcpyA(pszTempName, tempname);
906         HeapFree(GetProcessHeap(), 0, tempname);
907         return TRUE;
908     }
909
910     HeapFree(GetProcessHeap(), 0, tempname);
911
912     return FALSE;
913 }
914
915 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
916                              USHORT *pattribs, int *err, void *pv)
917 {
918     BY_HANDLE_FILE_INFORMATION finfo;
919     FILETIME filetime;
920     HANDLE handle;
921     DWORD attrs;
922     BOOL res;
923
924     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
925                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
926
927     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
928
929     res = GetFileInformationByHandle(handle, &finfo);
930     ok(res, "Expected GetFileInformationByHandle to succeed\n");
931    
932     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
933     FileTimeToDosDateTime(&filetime, pdate, ptime);
934
935     attrs = GetFileAttributes(pszName);
936     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
937
938     return (INT_PTR)handle;
939 }
940
941 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
942 {
943     char path[MAX_PATH];
944     char filename[MAX_PATH];
945
946     lstrcpyA(path, CURR_DIR);
947     lstrcatA(path, "\\");
948     lstrcatA(path, file);
949
950     lstrcpyA(filename, file);
951
952     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
953                       progress, get_open_info, compress);
954 }
955
956 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
957 {
958     ZeroMemory(pCabParams, sizeof(CCAB));
959
960     pCabParams->cb = max_size;
961     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
962     pCabParams->setID = 0xbeef;
963     pCabParams->iCab = 1;
964     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
965     lstrcatA(pCabParams->szCabPath, "\\");
966     lstrcpyA(pCabParams->szCab, name);
967 }
968
969 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
970 {
971     CCAB cabParams;
972     LPCSTR ptr;
973     HFCI hfci;
974     ERF erf;
975     BOOL res;
976
977     set_cab_parameters(&cabParams, name, max_size);
978
979     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
980                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
981                       get_temp_file, &cabParams, NULL);
982
983     ok(hfci != NULL, "Failed to create an FCI context\n");
984
985     ptr = files;
986     while (*ptr)
987     {
988         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
989         ok(res, "Failed to add file: %s\n", ptr);
990         ptr += lstrlen(ptr) + 1;
991     }
992
993     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
994     ok(res, "Failed to flush the cabinet\n");
995
996     res = FCIDestroy(hfci);
997     ok(res, "Failed to destroy the cabinet\n");
998 }
999
1000 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1001 {
1002     HKEY hkey;
1003     DWORD type, size;
1004
1005     if (RegOpenKey(HKEY_LOCAL_MACHINE,
1006                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1007         return FALSE;
1008
1009     size = MAX_PATH;
1010     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1011         RegCloseKey(hkey);
1012         return FALSE;
1013     }
1014
1015     size = MAX_PATH;
1016     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1017         RegCloseKey(hkey);
1018         return FALSE;
1019     }
1020
1021     RegCloseKey(hkey);
1022     return TRUE;
1023 }
1024
1025 static void create_file(const CHAR *name, DWORD size)
1026 {
1027     HANDLE file;
1028     DWORD written, left;
1029
1030     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1031     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1032     WriteFile(file, name, strlen(name), &written, NULL);
1033     WriteFile(file, "\n", strlen("\n"), &written, NULL);
1034
1035     left = size - lstrlen(name) - 1;
1036
1037     SetFilePointer(file, left, NULL, FILE_CURRENT);
1038     SetEndOfFile(file);
1039     
1040     CloseHandle(file);
1041 }
1042
1043 static void create_test_files(void)
1044 {
1045     CreateDirectoryA("msitest", NULL);
1046     create_file("msitest\\one.txt", 100);
1047     CreateDirectoryA("msitest\\first", NULL);
1048     create_file("msitest\\first\\two.txt", 100);
1049     CreateDirectoryA("msitest\\second", NULL);
1050     create_file("msitest\\second\\three.txt", 100);
1051
1052     create_file("four.txt", 100);
1053     create_file("five.txt", 100);
1054     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1055
1056     create_file("msitest\\filename", 100);
1057     create_file("msitest\\service.exe", 100);
1058
1059     DeleteFileA("four.txt");
1060     DeleteFileA("five.txt");
1061 }
1062
1063 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1064 {
1065     CHAR path[MAX_PATH];
1066
1067     lstrcpyA(path, PROG_FILES_DIR);
1068     lstrcatA(path, "\\");
1069     lstrcatA(path, rel_path);
1070
1071     if (is_file)
1072         return DeleteFileA(path);
1073     else
1074         return RemoveDirectoryA(path);
1075 }
1076
1077 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1078 {
1079     CHAR path[MAX_PATH];
1080
1081     lstrcpyA(path, COMMON_FILES_DIR);
1082     lstrcatA(path, "\\");
1083     lstrcatA(path, rel_path);
1084
1085     if (is_file)
1086         return DeleteFileA(path);
1087     else
1088         return RemoveDirectoryA(path);
1089 }
1090
1091 static void delete_test_files(void)
1092 {
1093     DeleteFileA("msitest.msi");
1094     DeleteFileA("msitest.cab");
1095     DeleteFileA("msitest\\second\\three.txt");
1096     DeleteFileA("msitest\\first\\two.txt");
1097     DeleteFileA("msitest\\one.txt");
1098     DeleteFileA("msitest\\service.exe");
1099     DeleteFileA("msitest\\filename");
1100     RemoveDirectoryA("msitest\\second");
1101     RemoveDirectoryA("msitest\\first");
1102     RemoveDirectoryA("msitest");
1103 }
1104
1105 static void write_file(const CHAR *filename, const char *data, int data_size)
1106 {
1107     DWORD size;
1108
1109     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1110                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1111
1112     WriteFile(hf, data, data_size, &size, NULL);
1113     CloseHandle(hf);
1114 }
1115
1116 static void write_msi_summary_info(MSIHANDLE db)
1117 {
1118     MSIHANDLE summary;
1119     UINT r;
1120
1121     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1122     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1123
1124     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1126
1127     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1128                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1130
1131     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1132     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1133
1134     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1135     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1136
1137     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1139
1140     /* write the summary changes back to the stream */
1141     r = MsiSummaryInfoPersist(summary);
1142     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1143
1144     MsiCloseHandle(summary);
1145 }
1146
1147 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1148 {
1149     MSIHANDLE db;
1150     UINT r;
1151     int j;
1152
1153     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1154     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1155
1156     /* import the tables into the database */
1157     for (j = 0; j < num_tables; j++)
1158     {
1159         const msi_table *table = &tables[j];
1160
1161         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1162
1163         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1164         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1165
1166         DeleteFileA(table->filename);
1167     }
1168
1169     write_msi_summary_info(db);
1170
1171     r = MsiDatabaseCommit(db);
1172     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1173
1174     MsiCloseHandle(db);
1175 }
1176
1177 static void check_service_is_installed(void)
1178 {
1179     SC_HANDLE scm, service;
1180     BOOL res;
1181
1182     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1183     ok(scm != NULL, "Failed to open the SC Manager\n");
1184
1185     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1186     ok(service != NULL, "Failed to open TestService\n");
1187
1188     res = DeleteService(service);
1189     ok(res, "Failed to delete TestService\n");
1190 }
1191
1192 static void test_MsiInstallProduct(void)
1193 {
1194     UINT r;
1195     CHAR path[MAX_PATH];
1196     LONG res;
1197     HKEY hkey;
1198     DWORD num, size, type;
1199
1200     create_test_files();
1201     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1202
1203     r = MsiInstallProductA(msifile, NULL);
1204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1205
1206     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1207     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1208     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1209     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1210     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1211     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1212     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1213     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1214     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1215     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1216     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1217     ok(delete_pf("msitest", FALSE), "File not installed\n");
1218
1219     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1221
1222     size = MAX_PATH;
1223     type = REG_SZ;
1224     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1226     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1227
1228     size = MAX_PATH;
1229     type = REG_SZ;
1230     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1231     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1232
1233     size = sizeof(num);
1234     type = REG_DWORD;
1235     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1237     ok(num == 314, "Expected 314, got %d\n", num);
1238
1239     size = MAX_PATH;
1240     type = REG_SZ;
1241     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1243     ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1244
1245     check_service_is_installed();
1246
1247     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1248
1249     delete_test_files();
1250 }
1251
1252 static void test_MsiSetComponentState(void)
1253 {
1254     INSTALLSTATE installed, action;
1255     MSIHANDLE package;
1256     char path[MAX_PATH];
1257     UINT r;
1258
1259     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1260
1261     CoInitialize(NULL);
1262
1263     lstrcpy(path, CURR_DIR);
1264     lstrcat(path, "\\");
1265     lstrcat(path, msifile);
1266
1267     r = MsiOpenPackage(path, &package);
1268     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1269
1270     r = MsiDoAction(package, "CostInitialize");
1271     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1272
1273     r = MsiDoAction(package, "FileCost");
1274     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1275
1276     r = MsiDoAction(package, "CostFinalize");
1277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1278
1279     r = MsiGetComponentState(package, "dangler", &installed, &action);
1280     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1281     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1282     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1283
1284     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1286
1287     MsiCloseHandle(package);
1288     CoUninitialize();
1289
1290     DeleteFileA(msifile);
1291 }
1292
1293 static void test_packagecoltypes(void)
1294 {
1295     MSIHANDLE hdb, view, rec;
1296     char path[MAX_PATH];
1297     LPCSTR query;
1298     UINT r, count;
1299
1300     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1301
1302     CoInitialize(NULL);
1303
1304     lstrcpy(path, CURR_DIR);
1305     lstrcat(path, "\\");
1306     lstrcat(path, msifile);
1307
1308     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1310
1311     query = "SELECT * FROM `Media`";
1312     r = MsiDatabaseOpenView( hdb, query, &view );
1313     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1314
1315     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1316     count = MsiRecordGetFieldCount( rec );
1317     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1318     ok(count == 6, "Expected 6, got %d\n", count);
1319     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1320     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1321     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1322     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1323     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1324     ok(check_record(rec, 6, "Source"), "wrong column label\n");
1325     MsiCloseHandle(rec);
1326
1327     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1328     count = MsiRecordGetFieldCount( rec );
1329     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1330     ok(count == 6, "Expected 6, got %d\n", count);
1331     ok(check_record(rec, 1, "i2"), "wrong column label\n");
1332     ok(check_record(rec, 2, "i4"), "wrong column label\n");
1333     ok(check_record(rec, 3, "L64"), "wrong column label\n");
1334     ok(check_record(rec, 4, "S255"), "wrong column label\n");
1335     ok(check_record(rec, 5, "S32"), "wrong column label\n");
1336     ok(check_record(rec, 6, "S72"), "wrong column label\n");
1337
1338     MsiCloseHandle(rec);
1339     MsiCloseHandle(view);
1340     MsiCloseHandle(hdb);
1341     DeleteFile(msifile);
1342 }
1343
1344 static void create_cc_test_files(void)
1345 {
1346     CCAB cabParams;
1347     HFCI hfci;
1348     ERF erf;
1349     static CHAR cab_context[] = "test%d.cab";
1350     BOOL res;
1351
1352     create_file("maximus", 500);
1353     create_file("augustus", 50000);
1354     create_file("caesar", 500);
1355
1356     set_cab_parameters(&cabParams, "test1.cab", 200);
1357
1358     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1359                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1360                       get_temp_file, &cabParams, cab_context);
1361     ok(hfci != NULL, "Failed to create an FCI context\n");
1362
1363     res = add_file(hfci, "maximus", tcompTYPE_MSZIP);
1364     ok(res, "Failed to add file maximus\n");
1365
1366     res = add_file(hfci, "augustus", tcompTYPE_MSZIP);
1367     ok(res, "Failed to add file augustus\n");
1368
1369     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1370     ok(res, "Failed to flush the cabinet\n");
1371
1372     res = FCIDestroy(hfci);
1373     ok(res, "Failed to destroy the cabinet\n");
1374
1375     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1376
1377     DeleteFile("maximus");
1378     DeleteFile("augustus");
1379     DeleteFile("caesar");
1380 }
1381
1382 static void delete_cab_files(void)
1383 {
1384     SHFILEOPSTRUCT shfl;
1385     CHAR path[MAX_PATH+10];
1386
1387     lstrcpyA(path, CURR_DIR);
1388     lstrcatA(path, "\\*.cab");
1389     path[strlen(path) + 1] = '\0';
1390
1391     shfl.hwnd = NULL;
1392     shfl.wFunc = FO_DELETE;
1393     shfl.pFrom = path;
1394     shfl.pTo = NULL;
1395     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1396
1397     SHFileOperation(&shfl);
1398 }
1399
1400 static void test_continuouscabs(void)
1401 {
1402     UINT r;
1403
1404     create_cc_test_files();
1405     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1406
1407     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1408
1409     r = MsiInstallProductA(msifile, NULL);
1410     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1411     todo_wine
1412     {
1413         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1414         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1415         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1416     }
1417     ok(delete_pf("msitest", FALSE), "File not installed\n");
1418
1419     delete_cab_files();
1420     DeleteFile(msifile);
1421 }
1422
1423 static void test_caborder(void)
1424 {
1425     UINT r;
1426
1427     create_file("imperator", 100);
1428     create_file("maximus", 500);
1429     create_file("augustus", 50000);
1430     create_file("caesar", 500);
1431
1432     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1433
1434     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1435
1436     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1437     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1438     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1439
1440     r = MsiInstallProductA(msifile, NULL);
1441     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1442     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1443     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1444     todo_wine
1445     {
1446         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1447         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1448     }
1449
1450     delete_cab_files();
1451
1452     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1453     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1454     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1455
1456     r = MsiInstallProductA(msifile, NULL);
1457     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1458     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1459     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1460     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1461     todo_wine
1462     {
1463         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1464     }
1465
1466     delete_cab_files();
1467     DeleteFile(msifile);
1468
1469     create_cc_test_files();
1470     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1471
1472     r = MsiInstallProductA(msifile, NULL);
1473     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1474     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1475     ok(!delete_pf("msitest", FALSE), "File is installed\n");
1476     todo_wine
1477     {
1478         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1479         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1480     }
1481
1482     delete_cab_files();
1483     DeleteFile(msifile);
1484
1485     create_cc_test_files();
1486     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1487
1488     r = MsiInstallProductA(msifile, NULL);
1489     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1490     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1491     todo_wine
1492     {
1493         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1494         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1495         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1496     }
1497
1498     delete_cab_files();
1499     DeleteFile("imperator");
1500     DeleteFile("maximus");
1501     DeleteFile("augustus");
1502     DeleteFile("caesar");
1503     DeleteFile(msifile);
1504 }
1505
1506 static void test_mixedmedia(void)
1507 {
1508     UINT r;
1509
1510     CreateDirectoryA("msitest", NULL);
1511     create_file("msitest\\maximus", 500);
1512     create_file("msitest\\augustus", 500);
1513     create_file("caesar", 500);
1514
1515     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1516
1517     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1518
1519     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1520
1521     r = MsiInstallProductA(msifile, NULL);
1522     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1523     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1524     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1525     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1526     ok(delete_pf("msitest", FALSE), "File not installed\n");
1527
1528     /* Delete the files in the temp (current) folder */
1529     DeleteFile("msitest\\maximus");
1530     DeleteFile("msitest\\augustus");
1531     RemoveDirectory("msitest");
1532     DeleteFile("caesar");
1533     DeleteFile("test1.cab");
1534     DeleteFile(msifile);
1535 }
1536
1537 static void test_samesequence(void)
1538 {
1539     UINT r;
1540
1541     create_cc_test_files();
1542     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1543
1544     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1545
1546     r = MsiInstallProductA(msifile, NULL);
1547     todo_wine
1548     {
1549         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1550         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1551         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1552     }
1553     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1554     ok(delete_pf("msitest", FALSE), "File not installed\n");
1555
1556     delete_cab_files();
1557     DeleteFile(msifile);
1558 }
1559
1560 static void test_uiLevelFlags(void)
1561 {
1562     UINT r;
1563
1564     create_cc_test_files();
1565     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1566
1567     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1568
1569     r = MsiInstallProductA(msifile, NULL);
1570     ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1571     todo_wine
1572     {
1573         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1574         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1575     }
1576     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1577     ok(delete_pf("msitest", FALSE), "File not installed\n");
1578
1579     delete_cab_files();
1580     DeleteFile(msifile);
1581 }
1582
1583 static BOOL file_matches(LPSTR path)
1584 {
1585     CHAR buf[MAX_PATH];
1586     HANDLE file;
1587     DWORD size;
1588
1589     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1590                       NULL, OPEN_EXISTING, 0, NULL);
1591
1592     ZeroMemory(buf, MAX_PATH);
1593     ReadFile(file, buf, 15, &size, NULL);
1594     CloseHandle(file);
1595
1596     return !lstrcmp(buf, "msitest\\maximus");
1597 }
1598
1599 static void test_readonlyfile(void)
1600 {
1601     UINT r;
1602     DWORD size;
1603     HANDLE file;
1604     CHAR path[MAX_PATH];
1605
1606     CreateDirectoryA("msitest", NULL);
1607     create_file("msitest\\maximus", 500);
1608     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1609
1610     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1611
1612     lstrcpy(path, PROG_FILES_DIR);
1613     lstrcat(path, "\\msitest");
1614     CreateDirectory(path, NULL);
1615
1616     lstrcat(path, "\\maximus");
1617     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1618                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1619
1620     WriteFile(file, "readonlyfile", 20, &size, NULL);
1621     CloseHandle(file);
1622
1623     r = MsiInstallProductA(msifile, NULL);
1624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1625     ok(file_matches(path), "Expected file to be overwritten\n");
1626     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1627     ok(delete_pf("msitest", FALSE), "File not installed\n");
1628
1629     /* Delete the files in the temp (current) folder */
1630     DeleteFile("msitest\\maximus");
1631     RemoveDirectory("msitest");
1632     DeleteFile(msifile);
1633 }
1634
1635 static void test_setdirproperty(void)
1636 {
1637     UINT r;
1638
1639     CreateDirectoryA("msitest", NULL);
1640     create_file("msitest\\maximus", 500);
1641     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1642
1643     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1644
1645     r = MsiInstallProductA(msifile, NULL);
1646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1647     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1648     ok(delete_cf("msitest", FALSE), "File not installed\n");
1649
1650     /* Delete the files in the temp (current) folder */
1651     DeleteFile(msifile);
1652     DeleteFile("msitest\\maximus");
1653     RemoveDirectory("msitest");
1654 }
1655
1656 static void test_cabisextracted(void)
1657 {
1658     UINT r;
1659
1660     CreateDirectoryA("msitest", NULL);
1661     create_file("msitest\\gaius", 500);
1662     create_file("maximus", 500);
1663     create_file("augustus", 500);
1664     create_file("caesar", 500);
1665
1666     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1667     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1668     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1669
1670     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
1671
1672     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1673
1674     r = MsiInstallProductA(msifile, NULL);
1675     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1676     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1677     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1678     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1679     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
1680     ok(delete_pf("msitest", FALSE), "File not installed\n");
1681
1682     /* Delete the files in the temp (current) folder */
1683     delete_cab_files();
1684     DeleteFile(msifile);
1685     DeleteFile("maximus");
1686     DeleteFile("augustus");
1687     DeleteFile("caesar");
1688     DeleteFile("msitest\\gaius");
1689     RemoveDirectory("msitest");
1690 }
1691
1692 static void test_concurrentinstall(void)
1693 {
1694     UINT r;
1695     CHAR path[MAX_PATH];
1696
1697     CreateDirectoryA("msitest", NULL);
1698     CreateDirectoryA("msitest\\msitest", NULL);
1699     create_file("msitest\\maximus", 500);
1700     create_file("msitest\\msitest\\augustus", 500);
1701
1702     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
1703
1704     lstrcpyA(path, CURR_DIR);
1705     lstrcatA(path, "\\msitest\\concurrent.msi");
1706     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
1707
1708     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1709
1710     r = MsiInstallProductA(msifile, NULL);
1711     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1712     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1713     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1714     ok(delete_pf("msitest", FALSE), "File not installed\n");
1715
1716     /* Delete the files in the temp (current) folder */
1717     DeleteFile(msifile);
1718     DeleteFile(path);
1719     DeleteFile("msitest\\msitest\\augustus");
1720     DeleteFile("msitest\\maximus");
1721     RemoveDirectory("msitest\\msitest");
1722     RemoveDirectory("msitest");
1723 }
1724
1725 static void test_setpropertyfolder(void)
1726 {
1727     UINT r;
1728
1729     CreateDirectoryA("msitest", NULL);
1730     create_file("msitest\\maximus", 500);
1731
1732     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
1733
1734     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1735
1736     r = MsiInstallProductA(msifile, NULL);
1737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1738     ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
1739     ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
1740     ok(delete_pf("msitest", FALSE), "File not installed\n");
1741
1742     /* Delete the files in the temp (current) folder */
1743     DeleteFile(msifile);
1744     DeleteFile("msitest\\maximus");
1745     RemoveDirectory("msitest");
1746 }
1747
1748 static BOOL file_exists(LPCSTR file)
1749 {
1750     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
1751 }
1752
1753 static BOOL pf_exists(LPCSTR file)
1754 {
1755     CHAR path[MAX_PATH];
1756
1757     lstrcpyA(path, PROG_FILES_DIR);
1758     lstrcatA(path, "\\");
1759     lstrcatA(path, file);
1760
1761     return file_exists(path);
1762 }
1763
1764 static void delete_pfmsitest_files(void)
1765 {
1766     SHFILEOPSTRUCT shfl;
1767     CHAR path[MAX_PATH+11];
1768
1769     lstrcpyA(path, PROG_FILES_DIR);
1770     lstrcatA(path, "\\msitest\\*");
1771     path[strlen(path) + 1] = '\0';
1772
1773     shfl.hwnd = NULL;
1774     shfl.wFunc = FO_DELETE;
1775     shfl.pFrom = path;
1776     shfl.pTo = NULL;
1777     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1778
1779     SHFileOperation(&shfl);
1780
1781     lstrcpyA(path, PROG_FILES_DIR);
1782     lstrcatA(path, "\\msitest");
1783     RemoveDirectoryA(path);
1784 }
1785
1786 static void test_publish(void)
1787 {
1788     UINT r;
1789     INSTALLSTATE state;
1790     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
1791
1792     CreateDirectoryA("msitest", NULL);
1793     create_file("msitest\\maximus", 500);
1794
1795     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
1796
1797     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1798
1799     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1800     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1801
1802     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1803     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1804
1805     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1806     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1807
1808     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1809                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1810     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1811     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1812
1813     /* nothing published */
1814     r = MsiInstallProductA(msifile, NULL);
1815     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1816     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1817     ok(pf_exists("msitest"), "File not installed\n");
1818
1819     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1820     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1821
1822     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1823     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1824
1825     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1826     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1827
1828     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1829                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1830     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1831     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1832
1833     /* install again */
1834     r = MsiInstallProductA(msifile, NULL);
1835     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1836     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1837     ok(pf_exists("msitest"), "File not installed\n");
1838
1839     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1840     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1841
1842     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1843     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1844
1845     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1846     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1847
1848     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1849                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1850     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1851     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1852
1853     /* try to uninstall */
1854     r = MsiInstallProductA(msifile, "REMOVE=ALL");
1855     todo_wine
1856     {
1857         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1858     }
1859     ok(pf_exists("msitest\\maximus"), "File deleted\n");
1860     ok(pf_exists("msitest"), "File deleted\n");
1861
1862     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1863     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1864
1865     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1866     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1867
1868     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1869     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1870
1871     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1872                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1873     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1874     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1875
1876     /* PublishProduct */
1877     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
1878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1879     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1880     ok(pf_exists("msitest"), "File not installed\n");
1881
1882     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1883     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1884
1885     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1886     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1887
1888     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1889                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1890     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1891     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1892
1893     /* try to uninstall after PublishProduct */
1894     r = MsiInstallProductA(msifile, "REMOVE=ALL");
1895     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1896     ok(pf_exists("msitest\\maximus"), "File deleted\n");
1897     ok(pf_exists("msitest"), "File deleted\n");
1898
1899     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1900     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1901
1902     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1903     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1904
1905     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1906     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1907
1908     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1909                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1910     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1911     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1912
1913     /* PublishProduct and RegisterProduct */
1914     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
1915     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1916     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1917     ok(pf_exists("msitest"), "File not installed\n");
1918
1919     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1920     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1921
1922     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1923     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1924
1925     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1926     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1927
1928     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1929                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1930     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1931     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1932
1933     /* try it again */
1934     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
1935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1936     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1937     ok(pf_exists("msitest"), "File not installed\n");
1938
1939     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1940     todo_wine
1941     {
1942         ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1943     }
1944
1945     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1946     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1947
1948     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1949     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1950
1951     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1952                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1953     todo_wine
1954     {
1955         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1956     }
1957     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1958
1959     /* uninstall has a problem with this */
1960     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
1961     todo_wine
1962     {
1963         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1964     }
1965     ok(pf_exists("msitest\\maximus"), "File deleted\n");
1966     ok(pf_exists("msitest"), "File deleted\n");
1967
1968     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1969     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1970
1971     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1972     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1973
1974     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1975                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1976     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1977     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1978
1979     /* PublishProduct and RegisterProduct and ProcessComponents */
1980     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
1981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1982     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1983     ok(pf_exists("msitest"), "File not installed\n");
1984
1985     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1986     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1987
1988     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1989     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1990
1991     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1992     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1993
1994     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1995                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1996     todo_wine
1997     {
1998         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1999         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2000     }
2001
2002     /* complete uninstall */
2003     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2005     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2006     ok(pf_exists("msitest"), "File deleted\n");
2007
2008     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2009     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2010
2011     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2012     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2013
2014     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2015     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2016
2017     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2018                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2019     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2020     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2021
2022     /* PublishProduct, RegisterProduct, ProcessComponents, PublishFeatures */
2023     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1 PUBLISH_FEATURES=1");
2024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2025     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2026     ok(pf_exists("msitest"), "File not installed\n");
2027
2028     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2029     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2030
2031     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2032     todo_wine
2033     {
2034         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2035     }
2036
2037     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2038     todo_wine
2039     {
2040         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2041     }
2042
2043     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2044                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2045     todo_wine
2046     {
2047         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2048         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2049     }
2050
2051     /* complete uninstall */
2052     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2054     todo_wine
2055     {
2056         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2057         ok(!pf_exists("msitest"), "File deleted\n");
2058     }
2059
2060     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2061     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2062
2063     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");\
2064     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2065
2066     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2067     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2068
2069     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2070                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2071     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2072     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2073
2074     /* complete install */
2075     r = MsiInstallProductA(msifile, "FULL=1");
2076     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2077     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2078     ok(pf_exists("msitest"), "File not installed\n");
2079
2080     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2081     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2082
2083     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2084     todo_wine
2085     {
2086         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2087     }
2088
2089     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2090     todo_wine
2091     {
2092         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2093     }
2094
2095     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2096                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2097     todo_wine
2098     {
2099         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2100         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2101     }
2102
2103     /* no UnpublishFeatures */
2104     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2106     todo_wine
2107     {
2108         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2109         ok(!pf_exists("msitest"), "File deleted\n");
2110     }
2111
2112     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2113     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2114
2115     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2116     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2117
2118     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2119     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2120
2121     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2122                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2123     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2124     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2125
2126     /* complete install */
2127     r = MsiInstallProductA(msifile, "FULL=1");
2128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2129     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2130     ok(pf_exists("msitest"), "File not installed\n");
2131
2132     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2133     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2134
2135     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2136     todo_wine
2137     {
2138         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2139     }
2140
2141     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2142     todo_wine
2143     {
2144         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2145     }
2146
2147     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2148                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2149     todo_wine
2150     {
2151         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2152         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2153     }
2154
2155     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
2156     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
2157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2158     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2159     ok(pf_exists("msitest"), "File deleted\n");
2160
2161     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2162     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2163
2164     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2165     todo_wine
2166     {
2167         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2168     }
2169
2170     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2171     todo_wine
2172     {
2173         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2174     }
2175
2176     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2177                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2178     todo_wine
2179     {
2180         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2181         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2182     }
2183
2184     /* complete install */
2185     r = MsiInstallProductA(msifile, "FULL=1");
2186     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2187     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2188     ok(pf_exists("msitest"), "File not installed\n");
2189
2190     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2191     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2192
2193     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2194     todo_wine
2195     {
2196         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2197     }
2198
2199     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2200     todo_wine
2201     {
2202         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2203     }
2204
2205     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2206                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2207     todo_wine
2208     {
2209         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2210         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2211     }
2212
2213     /* UnpublishFeatures, both features removed */
2214     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
2215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2216     todo_wine
2217     {
2218         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2219         ok(!pf_exists("msitest"), "File not deleted\n");
2220     }
2221
2222     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2223     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2224
2225     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2226     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2227
2228     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2229     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2230
2231     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2232                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2233     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2234     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2235
2236     /* complete install */
2237     r = MsiInstallProductA(msifile, "FULL=1");
2238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2239     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2240     ok(pf_exists("msitest"), "File not installed\n");
2241
2242     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2243     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2244
2245     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2246     todo_wine
2247     {
2248         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2249     }
2250
2251     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2252     todo_wine
2253     {
2254         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2255     }
2256
2257     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2258                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2259     todo_wine
2260     {
2261         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2262         ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2263     }
2264
2265     /* complete uninstall */
2266     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2267     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2268     todo_wine
2269     {
2270         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2271         ok(!pf_exists("msitest"), "File not deleted\n");
2272     }
2273
2274     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2275     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2276
2277     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2278     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2279
2280     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2281     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2282
2283     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2284                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2285     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2286     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2287
2288     /* make sure 'Program Files\msitest' is removed */
2289     delete_pfmsitest_files();
2290
2291     DeleteFile(msifile);
2292     DeleteFile("msitest\\maximus");
2293     RemoveDirectory("msitest");
2294 }
2295
2296 static void test_publishsourcelist(void)
2297 {
2298     UINT r;
2299     DWORD size;
2300     CHAR value[MAX_PATH];
2301     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2302
2303     CreateDirectoryA("msitest", NULL);
2304     create_file("msitest\\maximus", 500);
2305
2306     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2307
2308     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2309
2310     r = MsiInstallProductA(msifile, NULL);
2311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2312     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2313     ok(pf_exists("msitest"), "File not installed\n");
2314
2315     /* nothing published */
2316     size = 0xdeadbeef;
2317     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2318                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2319     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2320     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2321
2322     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2323     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2324     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2325     ok(pf_exists("msitest"), "File not installed\n");
2326
2327     /* after RegisterProduct */
2328     size = 0xdeadbeef;
2329     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2330                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2331     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2332     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2333
2334     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
2335     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2336     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2337     ok(pf_exists("msitest"), "File not installed\n");
2338
2339     /* after ProcessComponents */
2340     size = 0xdeadbeef;
2341     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2342                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2343     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2344     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2345
2346     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2347     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2348     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2349     ok(pf_exists("msitest"), "File not installed\n");
2350
2351     /* after PublishFeatures */
2352     size = 0xdeadbeef;
2353     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2354                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2355     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2356     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2357
2358     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2360     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2361     ok(pf_exists("msitest"), "File not installed\n");
2362
2363     /* after PublishProduct */
2364     size = MAX_PATH;
2365     lstrcpyA(value, "aaa");
2366     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2367                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
2368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2369     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
2370     ok(size == 11, "Expected 11, got %d\n", size);
2371
2372     /* complete uninstall */
2373     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2374     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2375     todo_wine
2376     {
2377         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2378         ok(!pf_exists("msitest"), "File not deleted\n");
2379     }
2380
2381     /* make sure 'Program Files\msitest' is removed */
2382     delete_pfmsitest_files();
2383
2384     DeleteFile(msifile);
2385     DeleteFile("msitest\\maximus");
2386     RemoveDirectory("msitest");
2387 }
2388
2389 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
2390 {
2391     MSIHANDLE hview = 0;
2392     UINT r;
2393
2394     r = MsiDatabaseOpenView(hdb, query, &hview);
2395     if(r != ERROR_SUCCESS)
2396         return r;
2397
2398     r = MsiViewExecute(hview, hrec);
2399     if(r == ERROR_SUCCESS)
2400         r = MsiViewClose(hview);
2401     MsiCloseHandle(hview);
2402     return r;
2403 }
2404
2405 static void set_transform_summary_info(void)
2406 {
2407     UINT r;
2408     MSIHANDLE suminfo;
2409
2410     /* build summmary info */
2411     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
2412     todo_wine
2413     {
2414         ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
2415     }
2416
2417     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2418     todo_wine
2419     {
2420         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2421     }
2422
2423     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2424                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2425                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2426                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
2427     todo_wine
2428     {
2429         ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
2430     }
2431
2432     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
2433     todo_wine
2434     {
2435         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2436     }
2437
2438     r = MsiSummaryInfoPersist(suminfo);
2439     todo_wine
2440     {
2441         ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
2442     }
2443
2444     r = MsiCloseHandle(suminfo);
2445     todo_wine
2446     {
2447         ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
2448     }
2449 }
2450
2451 static void generate_transform(void)
2452 {
2453     MSIHANDLE hdb1, hdb2;
2454     LPCSTR query;
2455     UINT r;
2456
2457     /* start with two identical databases */
2458     CopyFile(msifile, msifile2, FALSE);
2459
2460     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
2461     ok(r == ERROR_SUCCESS , "Failed to create database\n");
2462
2463     r = MsiDatabaseCommit(hdb1);
2464     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
2465
2466     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
2467     ok(r == ERROR_SUCCESS , "Failed to create database\n");
2468
2469     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
2470     r = run_query(hdb1, 0, query);
2471     ok(r == ERROR_SUCCESS, "failed to add property\n");
2472
2473     /* database needs to be committed */
2474     MsiDatabaseCommit(hdb1);
2475
2476     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
2477     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
2478
2479 #if 0  /* not implemented in wine yet */
2480     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
2481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2482 #endif
2483
2484     MsiCloseHandle(hdb1);
2485     MsiCloseHandle(hdb2);
2486 }
2487
2488 /* data for generating a transform */
2489
2490 /* tables transform names - encoded as they would be in an msi database file */
2491 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
2492 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
2493 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
2494
2495 /* data in each table */
2496 static const char data1[] = /* _StringData */
2497     "propval";  /* all the strings squashed together */
2498
2499 static const WCHAR data2[] = { /* _StringPool */
2500 /*  len, refs */
2501     0,   0,    /* string 0 ''     */
2502     4,   1,    /* string 1 'prop' */
2503     3,   1,    /* string 2 'val'  */
2504 };
2505
2506 static const WCHAR data3[] = { /* Property */
2507     0x0201, 0x0001, 0x0002,
2508 };
2509
2510 static const struct {
2511     LPCWSTR name;
2512     const void *data;
2513     DWORD size;
2514 } table_transform_data[] =
2515 {
2516     { name1, data1, sizeof data1 - 1 },
2517     { name2, data2, sizeof data2 },
2518     { name3, data3, sizeof data3 },
2519 };
2520
2521 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
2522
2523 static void generate_transform_manual(void)
2524 {
2525     IStorage *stg = NULL;
2526     IStream *stm;
2527     WCHAR name[0x20];
2528     HRESULT r;
2529     DWORD i, count;
2530     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
2531
2532     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
2533
2534     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
2535
2536     r = StgCreateDocfile(name, mode, 0, &stg);
2537     ok(r == S_OK, "failed to create storage\n");
2538     if (!stg)
2539         return;
2540
2541     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
2542     ok(r == S_OK, "failed to set storage type\n");
2543
2544     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
2545     {
2546         r = IStorage_CreateStream(stg, table_transform_data[i].name,
2547                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2548         if (FAILED(r))
2549         {
2550             ok(0, "failed to create stream %08x\n", r);
2551             continue;
2552         }
2553
2554         r = IStream_Write(stm, table_transform_data[i].data,
2555                           table_transform_data[i].size, &count);
2556         if (FAILED(r) || count != table_transform_data[i].size)
2557             ok(0, "failed to write stream\n");
2558         IStream_Release(stm);
2559     }
2560
2561     IStorage_Release(stg);
2562
2563     set_transform_summary_info();
2564 }
2565
2566 static void test_transformprop(void)
2567 {
2568     UINT r;
2569
2570     CreateDirectoryA("msitest", NULL);
2571     create_file("msitest\\augustus", 500);
2572
2573     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
2574
2575     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2576
2577     r = MsiInstallProductA(msifile, NULL);
2578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2579     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2580     ok(!delete_pf("msitest", FALSE), "File installed\n");
2581
2582     if (0)
2583         generate_transform();
2584     else
2585         generate_transform_manual();
2586
2587     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
2588     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2589     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2590     ok(delete_pf("msitest", FALSE), "File not installed\n");
2591
2592     /* Delete the files in the temp (current) folder */
2593     DeleteFile(msifile);
2594     DeleteFile(msifile2);
2595     DeleteFile(mstfile);
2596     DeleteFile("msitest\\augustus");
2597     RemoveDirectory("msitest");
2598 }
2599
2600 static void test_currentworkingdir(void)
2601 {
2602     UINT r;
2603     CHAR path[MAX_PATH];
2604     LPSTR ptr, ptr2;
2605
2606     CreateDirectoryA("msitest", NULL);
2607     create_file("msitest\\augustus", 500);
2608
2609     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
2610
2611     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2612
2613     CreateDirectoryA("diffdir", NULL);
2614     SetCurrentDirectoryA("diffdir");
2615
2616     sprintf(path, "..\\%s", msifile);
2617     r = MsiInstallProductA(path, NULL);
2618     todo_wine
2619     {
2620         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
2621         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2622         ok(!delete_pf("msitest", FALSE), "File installed\n");
2623     }
2624
2625     sprintf(path, "%s\\%s", CURR_DIR, msifile);
2626     r = MsiInstallProductA(path, NULL);
2627     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2628     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2629     ok(delete_pf("msitest", FALSE), "File not installed\n");
2630
2631     lstrcpyA(path, CURR_DIR);
2632     if (path[lstrlenA(path) - 1] != '\\')
2633         lstrcatA(path, "\\");
2634     lstrcatA(path, "msitest.msi");
2635
2636     ptr2 = strrchr(path, '\\');
2637     *ptr2 = '\0';
2638     ptr = strrchr(path, '\\');
2639     *ptr2 = '\\';
2640     *(ptr++) = '\0';
2641
2642     SetCurrentDirectoryA(path);
2643
2644     r = MsiInstallProductA(ptr, NULL);
2645     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2646     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2647     ok(delete_pf("msitest", FALSE), "File not installed\n");
2648
2649     SetCurrentDirectoryA(CURR_DIR);
2650
2651     DeleteFile(msifile);
2652     DeleteFile("msitest\\augustus");
2653     RemoveDirectory("msitest");
2654     RemoveDirectory("diffdir");
2655 }
2656
2657 static void set_admin_summary_info(const CHAR *name)
2658 {
2659     MSIHANDLE db, summary;
2660     UINT r;
2661
2662     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
2663     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2664
2665     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
2666     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2667
2668     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
2669     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2670
2671     /* write the summary changes back to the stream */
2672     r = MsiSummaryInfoPersist(summary);
2673     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2674
2675     MsiCloseHandle(summary);
2676
2677     r = MsiDatabaseCommit(db);
2678     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2679
2680     MsiCloseHandle(db);
2681 }
2682
2683 static void test_admin(void)
2684 {
2685     UINT r;
2686
2687     CreateDirectoryA("msitest", NULL);
2688     create_file("msitest\\augustus", 500);
2689
2690     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
2691     set_admin_summary_info(msifile);
2692
2693     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2694
2695     r = MsiInstallProductA(msifile, NULL);
2696     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2697     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2698     ok(!delete_pf("msitest", FALSE), "File installed\n");
2699     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
2700     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
2701
2702     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
2703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2704     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2705     ok(!delete_pf("msitest", FALSE), "File installed\n");
2706     todo_wine
2707     {
2708         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
2709         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
2710     }
2711
2712     DeleteFile(msifile);
2713     DeleteFile("msitest\\augustus");
2714     RemoveDirectory("msitest");
2715 }
2716
2717 static void set_admin_property_stream(LPCSTR file)
2718 {
2719     IStorage *stg;
2720     IStream *stm;
2721     WCHAR fileW[MAX_PATH];
2722     HRESULT hr;
2723     DWORD count;
2724     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
2725
2726     /* AdminProperties */
2727     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
2728     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
2729
2730     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
2731
2732     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
2733     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
2734     if (!stg)
2735         return;
2736
2737     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2738     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
2739
2740     hr = IStream_Write(stm, data, sizeof(data), &count);
2741     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
2742
2743     IStream_Release(stm);
2744     IStorage_Release(stg);
2745 }
2746
2747 static void test_adminprops(void)
2748 {
2749     UINT r;
2750
2751     CreateDirectoryA("msitest", NULL);
2752     create_file("msitest\\augustus", 500);
2753
2754     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
2755     set_admin_summary_info(msifile);
2756     set_admin_property_stream(msifile);
2757
2758     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2759
2760     r = MsiInstallProductA(msifile, NULL);
2761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2762     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
2763     ok(delete_pf("msitest", FALSE), "File installed\n");
2764
2765     DeleteFile(msifile);
2766     DeleteFile("msitest\\augustus");
2767     RemoveDirectory("msitest");
2768 }
2769
2770 static void create_pf(LPCSTR file, BOOL is_file)
2771 {
2772     CHAR path[MAX_PATH];
2773
2774     lstrcpyA(path, PROG_FILES_DIR);
2775     lstrcatA(path, "\\");
2776     lstrcatA(path, file);
2777
2778     if (is_file)
2779         create_file(path, 500);
2780     else
2781         CreateDirectoryA(path, NULL);
2782 }
2783
2784 static void test_removefiles(void)
2785 {
2786     UINT r;
2787
2788     CreateDirectoryA("msitest", NULL);
2789     create_file("msitest\\hydrogen", 500);
2790     create_file("msitest\\helium", 500);
2791     create_file("msitest\\lithium", 500);
2792
2793     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
2794
2795     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2796
2797     r = MsiInstallProductA(msifile, NULL);
2798     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2799     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
2800     ok(!pf_exists("msitest\\helium"), "File installed\n");
2801     ok(pf_exists("msitest\\lithium"), "File not installed\n");
2802     ok(pf_exists("msitest"), "File not installed\n");
2803
2804     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2806     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
2807     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
2808     todo_wine
2809     {
2810         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
2811         ok(delete_pf("msitest", FALSE), "File deleted\n");
2812     }
2813
2814     create_pf("msitest", FALSE);
2815     create_pf("msitest\\hydrogen", TRUE);
2816     create_pf("msitest\\helium", TRUE);
2817     create_pf("msitest\\lithium", TRUE);
2818
2819     r = MsiInstallProductA(msifile, NULL);
2820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2821     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
2822     ok(pf_exists("msitest\\helium"), "File not installed\n");
2823     ok(pf_exists("msitest\\lithium"), "File not installed\n");
2824     ok(pf_exists("msitest"), "File not installed\n");
2825
2826     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2827     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2828     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
2829     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
2830     todo_wine
2831     {
2832         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
2833         ok(delete_pf("msitest", FALSE), "File deleted\n");
2834     }
2835
2836     create_pf("msitest", FALSE);
2837     create_pf("msitest\\furlong", TRUE);
2838     create_pf("msitest\\firkin", TRUE);
2839     create_pf("msitest\\fortnight", TRUE);
2840     create_pf("msitest\\becquerel", TRUE);
2841     create_pf("msitest\\dioptre", TRUE);
2842     create_pf("msitest\\attoparsec", TRUE);
2843     create_pf("msitest\\storeys", TRUE);
2844     create_pf("msitest\\block", TRUE);
2845     create_pf("msitest\\siriometer", TRUE);
2846
2847     r = MsiInstallProductA(msifile, NULL);
2848     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2849     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
2850     ok(!pf_exists("msitest\\helium"), "File installed\n");
2851     ok(pf_exists("msitest\\lithium"), "File not installed\n");
2852     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
2853     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
2854     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
2855     ok(pf_exists("msitest"), "File not installed\n");
2856     todo_wine
2857     {
2858         ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
2859         ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
2860         ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
2861         ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
2862         ok(!pf_exists("msitest\\block"), "File not deleted\n");
2863         ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
2864     }
2865
2866     create_pf("msitest\\furlong", TRUE);
2867     create_pf("msitest\\firkin", TRUE);
2868     create_pf("msitest\\fortnight", TRUE);
2869     create_pf("msitest\\storeys", TRUE);
2870     create_pf("msitest\\block", TRUE);
2871     create_pf("msitest\\siriometer", TRUE);
2872
2873     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2875     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
2876     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
2877     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
2878     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
2879     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
2880     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
2881     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
2882     todo_wine
2883     {
2884         ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
2885         ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
2886         ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
2887         ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
2888         ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
2889     }
2890     ok(delete_pf("msitest", FALSE), "File deleted\n");
2891
2892     DeleteFile(msifile);
2893     DeleteFile("msitest\\hydrogen");
2894     DeleteFile("msitest\\helium");
2895     DeleteFile("msitest\\lithium");
2896     RemoveDirectory("msitest");
2897 }
2898
2899 START_TEST(install)
2900 {
2901     DWORD len;
2902     char temp_path[MAX_PATH], prev_path[MAX_PATH];
2903
2904     init_functionpointers();
2905
2906     GetCurrentDirectoryA(MAX_PATH, prev_path);
2907     GetTempPath(MAX_PATH, temp_path);
2908     SetCurrentDirectoryA(temp_path);
2909
2910     lstrcpyA(CURR_DIR, temp_path);
2911     len = lstrlenA(CURR_DIR);
2912
2913     if(len && (CURR_DIR[len - 1] == '\\'))
2914         CURR_DIR[len - 1] = 0;
2915
2916     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
2917
2918     test_MsiInstallProduct();
2919     test_MsiSetComponentState();
2920     test_packagecoltypes();
2921     test_continuouscabs();
2922     test_caborder();
2923     test_mixedmedia();
2924     test_samesequence();
2925     test_uiLevelFlags();
2926     test_readonlyfile();
2927     test_setdirproperty();
2928     test_cabisextracted();
2929     test_concurrentinstall();
2930     test_setpropertyfolder();
2931     test_publish();
2932     test_publishsourcelist();
2933     test_transformprop();
2934     test_currentworkingdir();
2935     test_admin();
2936     test_adminprops();
2937     test_removefiles();
2938
2939     SetCurrentDirectoryA(prev_path);
2940 }