msi: Actually delete the row data instead of blanking it out.
[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                                            "ResolveSource\t\t950\n"
113                                            "MoveFiles\t\t1700\n"
114                                            "InstallFiles\t\t4000\n"
115                                            "DuplicateFiles\t\t4500\n"
116                                            "InstallServices\t\t5000\n"
117                                            "InstallFinalize\t\t6600\n"
118                                            "InstallInitialize\t\t1500\n"
119                                            "InstallValidate\t\t1400\n"
120                                            "LaunchConditions\t\t100\n"
121                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
122
123 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
124                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
125                                 "Media\tDiskId\n"
126                                 "1\t3\t\t\tDISK1\t\n"
127                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
128
129 static const CHAR property_dat[] = "Property\tValue\n"
130                                    "s72\tl0\n"
131                                    "Property\tProperty\n"
132                                    "DefaultUIFont\tDlgFont8\n"
133                                    "HASUIRUN\t0\n"
134                                    "INSTALLLEVEL\t3\n"
135                                    "InstallMode\tTypical\n"
136                                    "Manufacturer\tWine\n"
137                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
138                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
139                                    "ProductID\tnone\n"
140                                    "ProductLanguage\t1033\n"
141                                    "ProductName\tMSITEST\n"
142                                    "ProductVersion\t1.1.1\n"
143                                    "PROMPTROLLBACKCOST\tP\n"
144                                    "Setup\tSetup\n"
145                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
146                                    "AdminProperties\tPOSTADMIN\n"
147                                    "ROOTDRIVE\tC:\\\n";
148
149 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
150                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
151                                    "Registry\tRegistry\n"
152                                    "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
153                                    "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
154                                    "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
155                                    "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
156
157 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
158                                           "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
159                                           "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
160                                           "ServiceInstall\tServiceInstall\n"
161                                           "TestService\tTestService\tTestService\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
162
163 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
164                                           "s72\tl255\ti2\tL255\tI2\ts72\n"
165                                           "ServiceControl\tServiceControl\n"
166                                           "ServiceControl\tTestService\t8\t\t0\tservice_comp";
167
168 /* tables for test_continuouscabs */
169 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
170                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
171                                        "Component\tComponent\n"
172                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
173                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
174                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
175
176 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
177                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
178                                      "Feature\tFeature\n"
179                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
180
181 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
182                                           "s38\ts72\n"
183                                           "FeatureComponents\tFeature_\tComponent_\n"
184                                           "feature\tmaximus\n"
185                                           "feature\taugustus\n"
186                                           "feature\tcaesar";
187
188 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
189                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
190                                   "File\tFile\n"
191                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
192                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
193                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
194
195 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
196                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
197                                    "Media\tDiskId\n"
198                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
199                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
200                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
201
202 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
203                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
204                                   "File\tFile\n"
205                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
206                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
207                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
208
209 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
210                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
211                                    "Media\tDiskId\n"
212                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
213                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
214                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
215
216 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
217                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
218                                     "Media\tDiskId\n"
219                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
220                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
221                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
222
223 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
224                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
225                                   "File\tFile\n"
226                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
227                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
228                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
229
230 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
231                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
232                                    "Media\tDiskId\n"
233                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
234
235 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
236                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
237                                    "Media\tDiskId\n"
238                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
239                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
240                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
241
242 /* tables for test_uiLevelFlags */
243 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
244                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
245                                        "Component\tComponent\n"
246                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
247                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
248                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
249
250 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
251                                            "s72\tS255\tI2\n"
252                                            "InstallUISequence\tAction\n"
253                                            "SetUIProperty\t\t5\n"
254                                            "ExecuteAction\t\t1100\n";
255
256 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
257                                            "s72\ti2\tS64\tS0\tS255\n"
258                                            "CustomAction\tAction\n"
259                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
260
261 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
262                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
263                                         "Component\tComponent\n"
264                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
265
266 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
267                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
268                                       "Feature\tFeature\n"
269                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
270                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
271
272 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
273                                            "s38\ts72\n"
274                                            "FeatureComponents\tFeature_\tComponent_\n"
275                                            "feature\tmaximus\n"
276                                            "montecristo\tmaximus";
277
278 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
279                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
280                                    "File\tFile\n"
281                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
282
283 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
284                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
285                                     "Media\tDiskId\n"
286                                     "1\t1\t\t\tDISK1\t\n";
287
288 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
289                                                "s72\tS255\tI2\n"
290                                                "InstallExecuteSequence\tAction\n"
291                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
292                                                "CostFinalize\t\t1000\n"
293                                                "CostInitialize\t\t800\n"
294                                                "FileCost\t\t900\n"
295                                                "InstallFiles\t\t4000\n"
296                                                "InstallFinalize\t\t6600\n"
297                                                "InstallInitialize\t\t1500\n"
298                                                "InstallValidate\t\t1400\n"
299                                                "LaunchConditions\t\t100\n"
300                                                "SetDirProperty\t\t950";
301
302 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
303                                             "s72\ti2\tS64\tS0\tS255\n"
304                                             "CustomAction\tAction\n"
305                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
306
307 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
308                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
309                                         "Component\tComponent\n"
310                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
311                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
312                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
313                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
314
315 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
316                                            "s38\ts72\n"
317                                            "FeatureComponents\tFeature_\tComponent_\n"
318                                            "feature\tmaximus\n"
319                                            "feature\taugustus\n"
320                                            "feature\tcaesar\n"
321                                            "feature\tgaius";
322
323 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
324                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
325                                    "File\tFile\n"
326                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
327                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
328                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
329                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
330
331 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
332                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
333                                     "Media\tDiskId\n"
334                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
335                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
336                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
337
338 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
339                                               "s72\tS255\tI2\n"
340                                               "InstallExecuteSequence\tAction\n"
341                                               "CostFinalize\t\t1000\n"
342                                               "CostInitialize\t\t800\n"
343                                               "FileCost\t\t900\n"
344                                               "InstallFiles\t\t4000\n"
345                                               "InstallServices\t\t5000\n"
346                                               "InstallFinalize\t\t6600\n"
347                                               "InstallInitialize\t\t1500\n"
348                                               "RunInstall\t\t1600\n"
349                                               "InstallValidate\t\t1400\n"
350                                               "LaunchConditions\t\t100";
351
352 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
353                                             "s72\ti2\tS64\tS0\tS255\n"
354                                             "CustomAction\tAction\n"
355                                             "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
356
357 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
358                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
359                                        "Component\tComponent\n"
360                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
361
362 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
363                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
364                                         "Component\tComponent\n"
365                                         "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
366
367 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
368                                            "s38\ts72\n"
369                                            "FeatureComponents\tFeature_\tComponent_\n"
370                                            "feature\taugustus";
371
372 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
373                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
374                                    "File\tFile\n"
375                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
376
377 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
378                                             "s72\ti2\tS64\tS0\tS255\n"
379                                             "CustomAction\tAction\n"
380                                             "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
381
382 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
383                                                "s72\tS255\tI2\n"
384                                                "InstallExecuteSequence\tAction\n"
385                                                "CostFinalize\t\t1000\n"
386                                                "CostInitialize\t\t800\n"
387                                                "FileCost\t\t900\n"
388                                                "SetFolderProp\t\t950\n"
389                                                "InstallFiles\t\t4000\n"
390                                                "InstallServices\t\t5000\n"
391                                                "InstallFinalize\t\t6600\n"
392                                                "InstallInitialize\t\t1500\n"
393                                                "InstallValidate\t\t1400\n"
394                                                "LaunchConditions\t\t100";
395
396 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
397                                              "s72\tS255\tI2\n"
398                                              "InstallUISequence\tAction\n"
399                                              "CostInitialize\t\t800\n"
400                                              "FileCost\t\t900\n"
401                                              "CostFinalize\t\t1000\n"
402                                              "ExecuteAction\t\t1100\n";
403
404 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
405                                               "s72\tS255\tI2\n"
406                                               "InstallExecuteSequence\tAction\n"
407                                               "ValidateProductID\t\t700\n"
408                                               "CostInitialize\t\t800\n"
409                                               "FileCost\t\t900\n"
410                                               "CostFinalize\t\t1000\n"
411                                               "InstallValidate\t\t1400\n"
412                                               "InstallInitialize\t\t1500\n"
413                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
414                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
415                                               "RemoveFiles\t\t3500\n"
416                                               "InstallFiles\t\t4000\n"
417                                               "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
418                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
419                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
420                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
421                                               "InstallFinalize\t\t6600";
422
423 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
424                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
425                                        "Component\tComponent\n"
426                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
427
428 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
429                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
430                                         "Component\tComponent\n"
431                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
432
433 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
434                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
435                                         "Component\tComponent\n"
436                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
437
438 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
439                                             "s72\ti2\tS64\tS0\tS255\n"
440                                             "CustomAction\tAction\n"
441                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
442
443 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
444                                              "s72\tS255\tI2\n"
445                                              "AdminExecuteSequence\tAction\n"
446                                              "CostFinalize\t\t1000\n"
447                                              "CostInitialize\t\t800\n"
448                                              "FileCost\t\t900\n"
449                                              "SetPOSTADMIN\t\t950\n"
450                                              "InstallFiles\t\t4000\n"
451                                              "InstallFinalize\t\t6600\n"
452                                              "InstallInitialize\t\t1500\n"
453                                              "InstallValidate\t\t1400\n"
454                                              "LaunchConditions\t\t100";
455
456 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
457                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
458                                         "Component\tComponent\n"
459                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718\taugustus\n";
460
461 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
462                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
463                                         "Component\tComponent\n"
464                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
465                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
466                                         "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
467
468 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
469                                            "s38\ts72\n"
470                                            "FeatureComponents\tFeature_\tComponent_\n"
471                                            "feature\thydrogen\n"
472                                            "feature\thelium\n"
473                                            "feature\tlithium";
474
475 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
476                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
477                                    "File\tFile\n"
478                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
479                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
480                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
481
482 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
483                                                "s72\tS255\tI2\n"
484                                                "InstallExecuteSequence\tAction\n"
485                                                "ValidateProductID\t\t700\n"
486                                                "CostInitialize\t\t800\n"
487                                                "FileCost\t\t900\n"
488                                                "CostFinalize\t\t1000\n"
489                                                "InstallValidate\t\t1400\n"
490                                                "InstallInitialize\t\t1500\n"
491                                                "ProcessComponents\t\t1600\n"
492                                                "UnpublishFeatures\t\t1800\n"
493                                                "RemoveFiles\t\t3500\n"
494                                                "InstallFiles\t\t4000\n"
495                                                "RegisterProduct\t\t6100\n"
496                                                "PublishFeatures\t\t6300\n"
497                                                "PublishProduct\t\t6400\n"
498                                                "InstallFinalize\t\t6600";
499
500 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
501                                            "s72\ts72\tS255\ts72\tI2\n"
502                                            "RemoveFile\tFileKey\n"
503                                            "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
504                                            "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
505                                            "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
506                                            "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
507                                            "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
508                                            "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
509                                            "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
510                                            "block\thelium\tblock\tMSITESTDIR\t3\n"
511                                            "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n";
512
513 static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
514                                         "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
515                                         "MoveFile\tFileKey\n"
516                                         "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
517                                         "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
518                                         "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
519                                         "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
520                                         "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
521                                         "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
522                                         "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
523                                         "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
524                                         "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
525                                         "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
526                                         "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
527                                         "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
528                                         "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
529                                         "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
530                                         "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
531                                         "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
532                                         "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
533
534 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
535                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
536                                         "Component\tComponent\n"
537                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
538                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
539                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
540                                         "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
541
542 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
543                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
544                                   "File\tFile\n"
545                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
546                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
547                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
548                                   "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
549
550 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
551                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
552                                    "Media\tDiskId\n"
553                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
554                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
555                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
556                                    "4\t4\t\ttest3.cab\tDISK3\t\n";
557
558 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
559                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
560                                        "MsiFileHash\tFile_\n"
561                                        "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
562
563 static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
564                                        "s72\tS72\tl255\n"
565                                        "Directory\tDirectory\n"
566                                        "THIS\tMSITESTDIR\tthis\n"
567                                        "DOESNT\tTHIS\tdoesnt\n"
568                                        "NONEXISTENT\tDOESNT\texist\n"
569                                        "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
570                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
571                                        "TARGETDIR\t\tSourceDir";
572
573 static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
574                                             "s72\ts72\ts72\tS255\tS72\n"
575                                             "DuplicateFile\tFileKey\n"
576                                             "maximus\tmaximus\tmaximus\taugustus\t\n"
577                                             "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n";
578
579 typedef struct _msi_table
580 {
581     const CHAR *filename;
582     const CHAR *data;
583     int size;
584 } msi_table;
585
586 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
587
588 static const msi_table tables[] =
589 {
590     ADD_TABLE(component),
591     ADD_TABLE(directory),
592     ADD_TABLE(feature),
593     ADD_TABLE(feature_comp),
594     ADD_TABLE(file),
595     ADD_TABLE(install_exec_seq),
596     ADD_TABLE(media),
597     ADD_TABLE(property),
598     ADD_TABLE(registry),
599     ADD_TABLE(service_install),
600     ADD_TABLE(service_control)
601 };
602
603 static const msi_table cc_tables[] =
604 {
605     ADD_TABLE(cc_component),
606     ADD_TABLE(directory),
607     ADD_TABLE(cc_feature),
608     ADD_TABLE(cc_feature_comp),
609     ADD_TABLE(cc_file),
610     ADD_TABLE(install_exec_seq),
611     ADD_TABLE(cc_media),
612     ADD_TABLE(property),
613 };
614
615 static const msi_table co_tables[] =
616 {
617     ADD_TABLE(cc_component),
618     ADD_TABLE(directory),
619     ADD_TABLE(cc_feature),
620     ADD_TABLE(cc_feature_comp),
621     ADD_TABLE(co_file),
622     ADD_TABLE(install_exec_seq),
623     ADD_TABLE(co_media),
624     ADD_TABLE(property),
625 };
626
627 static const msi_table co2_tables[] =
628 {
629     ADD_TABLE(cc_component),
630     ADD_TABLE(directory),
631     ADD_TABLE(cc_feature),
632     ADD_TABLE(cc_feature_comp),
633     ADD_TABLE(cc_file),
634     ADD_TABLE(install_exec_seq),
635     ADD_TABLE(co2_media),
636     ADD_TABLE(property),
637 };
638
639 static const msi_table mm_tables[] =
640 {
641     ADD_TABLE(cc_component),
642     ADD_TABLE(directory),
643     ADD_TABLE(cc_feature),
644     ADD_TABLE(cc_feature_comp),
645     ADD_TABLE(mm_file),
646     ADD_TABLE(install_exec_seq),
647     ADD_TABLE(mm_media),
648     ADD_TABLE(property),
649 };
650
651 static const msi_table ss_tables[] =
652 {
653     ADD_TABLE(cc_component),
654     ADD_TABLE(directory),
655     ADD_TABLE(cc_feature),
656     ADD_TABLE(cc_feature_comp),
657     ADD_TABLE(cc_file),
658     ADD_TABLE(install_exec_seq),
659     ADD_TABLE(ss_media),
660     ADD_TABLE(property),
661 };
662
663 static const msi_table ui_tables[] =
664 {
665     ADD_TABLE(ui_component),
666     ADD_TABLE(directory),
667     ADD_TABLE(cc_feature),
668     ADD_TABLE(cc_feature_comp),
669     ADD_TABLE(cc_file),
670     ADD_TABLE(install_exec_seq),
671     ADD_TABLE(ui_install_ui_seq),
672     ADD_TABLE(ui_custom_action),
673     ADD_TABLE(cc_media),
674     ADD_TABLE(property),
675 };
676
677 static const msi_table rof_tables[] =
678 {
679     ADD_TABLE(rof_component),
680     ADD_TABLE(directory),
681     ADD_TABLE(rof_feature),
682     ADD_TABLE(rof_feature_comp),
683     ADD_TABLE(rof_file),
684     ADD_TABLE(install_exec_seq),
685     ADD_TABLE(rof_media),
686     ADD_TABLE(property),
687 };
688
689 static const msi_table sdp_tables[] =
690 {
691     ADD_TABLE(rof_component),
692     ADD_TABLE(directory),
693     ADD_TABLE(rof_feature),
694     ADD_TABLE(rof_feature_comp),
695     ADD_TABLE(rof_file),
696     ADD_TABLE(sdp_install_exec_seq),
697     ADD_TABLE(sdp_custom_action),
698     ADD_TABLE(rof_media),
699     ADD_TABLE(property),
700 };
701
702 static const msi_table cie_tables[] =
703 {
704     ADD_TABLE(cie_component),
705     ADD_TABLE(directory),
706     ADD_TABLE(cc_feature),
707     ADD_TABLE(cie_feature_comp),
708     ADD_TABLE(cie_file),
709     ADD_TABLE(install_exec_seq),
710     ADD_TABLE(cie_media),
711     ADD_TABLE(property),
712 };
713
714 static const msi_table ci_tables[] =
715 {
716     ADD_TABLE(ci_component),
717     ADD_TABLE(directory),
718     ADD_TABLE(rof_feature),
719     ADD_TABLE(rof_feature_comp),
720     ADD_TABLE(rof_file),
721     ADD_TABLE(ci_install_exec_seq),
722     ADD_TABLE(rof_media),
723     ADD_TABLE(property),
724     ADD_TABLE(ci_custom_action),
725 };
726
727 static const msi_table ci2_tables[] =
728 {
729     ADD_TABLE(ci2_component),
730     ADD_TABLE(directory),
731     ADD_TABLE(rof_feature),
732     ADD_TABLE(ci2_feature_comp),
733     ADD_TABLE(ci2_file),
734     ADD_TABLE(install_exec_seq),
735     ADD_TABLE(rof_media),
736     ADD_TABLE(property),
737 };
738
739 static const msi_table spf_tables[] =
740 {
741     ADD_TABLE(ci_component),
742     ADD_TABLE(directory),
743     ADD_TABLE(rof_feature),
744     ADD_TABLE(rof_feature_comp),
745     ADD_TABLE(rof_file),
746     ADD_TABLE(spf_install_exec_seq),
747     ADD_TABLE(rof_media),
748     ADD_TABLE(property),
749     ADD_TABLE(spf_custom_action),
750     ADD_TABLE(spf_install_ui_seq),
751 };
752
753 static const msi_table pp_tables[] =
754 {
755     ADD_TABLE(ci_component),
756     ADD_TABLE(directory),
757     ADD_TABLE(rof_feature),
758     ADD_TABLE(rof_feature_comp),
759     ADD_TABLE(rof_file),
760     ADD_TABLE(pp_install_exec_seq),
761     ADD_TABLE(rof_media),
762     ADD_TABLE(property),
763 };
764
765 static const msi_table tp_tables[] =
766 {
767     ADD_TABLE(tp_component),
768     ADD_TABLE(directory),
769     ADD_TABLE(rof_feature),
770     ADD_TABLE(ci2_feature_comp),
771     ADD_TABLE(ci2_file),
772     ADD_TABLE(install_exec_seq),
773     ADD_TABLE(rof_media),
774     ADD_TABLE(property),
775 };
776
777 static const msi_table cwd_tables[] =
778 {
779     ADD_TABLE(cwd_component),
780     ADD_TABLE(directory),
781     ADD_TABLE(rof_feature),
782     ADD_TABLE(ci2_feature_comp),
783     ADD_TABLE(ci2_file),
784     ADD_TABLE(install_exec_seq),
785     ADD_TABLE(rof_media),
786     ADD_TABLE(property),
787 };
788
789 static const msi_table adm_tables[] =
790 {
791     ADD_TABLE(adm_component),
792     ADD_TABLE(directory),
793     ADD_TABLE(rof_feature),
794     ADD_TABLE(ci2_feature_comp),
795     ADD_TABLE(ci2_file),
796     ADD_TABLE(install_exec_seq),
797     ADD_TABLE(rof_media),
798     ADD_TABLE(property),
799     ADD_TABLE(adm_custom_action),
800     ADD_TABLE(adm_admin_exec_seq),
801 };
802
803 static const msi_table amp_tables[] =
804 {
805     ADD_TABLE(amp_component),
806     ADD_TABLE(directory),
807     ADD_TABLE(rof_feature),
808     ADD_TABLE(ci2_feature_comp),
809     ADD_TABLE(ci2_file),
810     ADD_TABLE(install_exec_seq),
811     ADD_TABLE(rof_media),
812     ADD_TABLE(property),
813 };
814
815 static const msi_table rem_tables[] =
816 {
817     ADD_TABLE(rem_component),
818     ADD_TABLE(directory),
819     ADD_TABLE(rof_feature),
820     ADD_TABLE(rem_feature_comp),
821     ADD_TABLE(rem_file),
822     ADD_TABLE(rem_install_exec_seq),
823     ADD_TABLE(rof_media),
824     ADD_TABLE(property),
825     ADD_TABLE(rem_remove_files),
826 };
827
828 static const msi_table mov_tables[] =
829 {
830     ADD_TABLE(cwd_component),
831     ADD_TABLE(directory),
832     ADD_TABLE(rof_feature),
833     ADD_TABLE(ci2_feature_comp),
834     ADD_TABLE(ci2_file),
835     ADD_TABLE(install_exec_seq),
836     ADD_TABLE(rof_media),
837     ADD_TABLE(property),
838     ADD_TABLE(mov_move_file),
839 };
840
841 static const msi_table mc_tables[] =
842 {
843     ADD_TABLE(mc_component),
844     ADD_TABLE(directory),
845     ADD_TABLE(cc_feature),
846     ADD_TABLE(cie_feature_comp),
847     ADD_TABLE(mc_file),
848     ADD_TABLE(install_exec_seq),
849     ADD_TABLE(mc_media),
850     ADD_TABLE(property),
851     ADD_TABLE(mc_file_hash),
852 };
853
854 static const msi_table df_tables[] =
855 {
856     ADD_TABLE(rof_component),
857     ADD_TABLE(df_directory),
858     ADD_TABLE(rof_feature),
859     ADD_TABLE(rof_feature_comp),
860     ADD_TABLE(rof_file),
861     ADD_TABLE(install_exec_seq),
862     ADD_TABLE(rof_media),
863     ADD_TABLE(property),
864     ADD_TABLE(df_duplicate_file),
865 };
866
867 /* cabinet definitions */
868
869 /* make the max size large so there is only one cab file */
870 #define MEDIA_SIZE          0x7FFFFFFF
871 #define FOLDER_THRESHOLD    900000
872
873 /* the FCI callbacks */
874
875 static void *mem_alloc(ULONG cb)
876 {
877     return HeapAlloc(GetProcessHeap(), 0, cb);
878 }
879
880 static void mem_free(void *memory)
881 {
882     HeapFree(GetProcessHeap(), 0, memory);
883 }
884
885 static BOOL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
886 {
887     sprintf(pccab->szCab, pv, pccab->iCab);
888     return TRUE;
889 }
890
891 static long progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
892 {
893     return 0;
894 }
895
896 static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
897                        BOOL fContinuation, void *pv)
898 {
899     return 0;
900 }
901
902 static INT_PTR fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
903 {
904     HANDLE handle;
905     DWORD dwAccess = 0;
906     DWORD dwShareMode = 0;
907     DWORD dwCreateDisposition = OPEN_EXISTING;
908     
909     dwAccess = GENERIC_READ | GENERIC_WRITE;
910     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
911     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
912
913     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
914         dwCreateDisposition = OPEN_EXISTING;
915     else
916         dwCreateDisposition = CREATE_NEW;
917
918     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
919                          dwCreateDisposition, 0, NULL);
920
921     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
922
923     return (INT_PTR)handle;
924 }
925
926 static UINT fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
927 {
928     HANDLE handle = (HANDLE)hf;
929     DWORD dwRead;
930     BOOL res;
931     
932     res = ReadFile(handle, memory, cb, &dwRead, NULL);
933     ok(res, "Failed to ReadFile\n");
934
935     return dwRead;
936 }
937
938 static UINT fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
939 {
940     HANDLE handle = (HANDLE)hf;
941     DWORD dwWritten;
942     BOOL res;
943
944     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
945     ok(res, "Failed to WriteFile\n");
946
947     return dwWritten;
948 }
949
950 static int fci_close(INT_PTR hf, int *err, void *pv)
951 {
952     HANDLE handle = (HANDLE)hf;
953     ok(CloseHandle(handle), "Failed to CloseHandle\n");
954
955     return 0;
956 }
957
958 static long fci_seek(INT_PTR hf, long dist, int seektype, int *err, void *pv)
959 {
960     HANDLE handle = (HANDLE)hf;
961     DWORD ret;
962     
963     ret = SetFilePointer(handle, dist, NULL, seektype);
964     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
965
966     return ret;
967 }
968
969 static int fci_delete(char *pszFile, int *err, void *pv)
970 {
971     BOOL ret = DeleteFileA(pszFile);
972     ok(ret, "Failed to DeleteFile %s\n", pszFile);
973
974     return 0;
975 }
976
977 static void init_functionpointers(void)
978 {
979     HMODULE hmsi = GetModuleHandleA("msi.dll");
980
981 #define GET_PROC(func) \
982     p ## func = (void*)GetProcAddress(hmsi, #func); \
983     if(!p ## func) \
984       trace("GetProcAddress(%s) failed\n", #func);
985
986     GET_PROC(MsiQueryComponentStateA);
987     GET_PROC(MsiSourceListGetInfoA);
988
989 #undef GET_PROC
990 }
991
992 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
993 {
994     CHAR buffer[0x20];
995     UINT r;
996     DWORD sz;
997
998     sz = sizeof buffer;
999     r = MsiRecordGetString(rec, field, buffer, &sz);
1000     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1001 }
1002
1003 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
1004 {
1005     LPSTR tempname;
1006
1007     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
1008     GetTempFileNameA(".", "xx", 0, tempname);
1009
1010     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
1011     {
1012         lstrcpyA(pszTempName, tempname);
1013         HeapFree(GetProcessHeap(), 0, tempname);
1014         return TRUE;
1015     }
1016
1017     HeapFree(GetProcessHeap(), 0, tempname);
1018
1019     return FALSE;
1020 }
1021
1022 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
1023                              USHORT *pattribs, int *err, void *pv)
1024 {
1025     BY_HANDLE_FILE_INFORMATION finfo;
1026     FILETIME filetime;
1027     HANDLE handle;
1028     DWORD attrs;
1029     BOOL res;
1030
1031     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
1032                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1033
1034     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
1035
1036     res = GetFileInformationByHandle(handle, &finfo);
1037     ok(res, "Expected GetFileInformationByHandle to succeed\n");
1038    
1039     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
1040     FileTimeToDosDateTime(&filetime, pdate, ptime);
1041
1042     attrs = GetFileAttributes(pszName);
1043     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
1044
1045     return (INT_PTR)handle;
1046 }
1047
1048 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
1049 {
1050     char path[MAX_PATH];
1051     char filename[MAX_PATH];
1052
1053     lstrcpyA(path, CURR_DIR);
1054     lstrcatA(path, "\\");
1055     lstrcatA(path, file);
1056
1057     lstrcpyA(filename, file);
1058
1059     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
1060                       progress, get_open_info, compress);
1061 }
1062
1063 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
1064 {
1065     ZeroMemory(pCabParams, sizeof(CCAB));
1066
1067     pCabParams->cb = max_size;
1068     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
1069     pCabParams->setID = 0xbeef;
1070     pCabParams->iCab = 1;
1071     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
1072     lstrcatA(pCabParams->szCabPath, "\\");
1073     lstrcpyA(pCabParams->szCab, name);
1074 }
1075
1076 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
1077 {
1078     CCAB cabParams;
1079     LPCSTR ptr;
1080     HFCI hfci;
1081     ERF erf;
1082     BOOL res;
1083
1084     set_cab_parameters(&cabParams, name, max_size);
1085
1086     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1087                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1088                       get_temp_file, &cabParams, NULL);
1089
1090     ok(hfci != NULL, "Failed to create an FCI context\n");
1091
1092     ptr = files;
1093     while (*ptr)
1094     {
1095         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
1096         ok(res, "Failed to add file: %s\n", ptr);
1097         ptr += lstrlen(ptr) + 1;
1098     }
1099
1100     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1101     ok(res, "Failed to flush the cabinet\n");
1102
1103     res = FCIDestroy(hfci);
1104     ok(res, "Failed to destroy the cabinet\n");
1105 }
1106
1107 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1108 {
1109     HKEY hkey;
1110     DWORD type, size;
1111
1112     if (RegOpenKey(HKEY_LOCAL_MACHINE,
1113                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1114         return FALSE;
1115
1116     size = MAX_PATH;
1117     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1118         RegCloseKey(hkey);
1119         return FALSE;
1120     }
1121
1122     size = MAX_PATH;
1123     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1124         RegCloseKey(hkey);
1125         return FALSE;
1126     }
1127
1128     RegCloseKey(hkey);
1129     return TRUE;
1130 }
1131
1132 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1133 {
1134     HANDLE file;
1135     DWORD written;
1136
1137     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1138     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1139     WriteFile(file, data, strlen(data), &written, NULL);
1140
1141     if (size)
1142     {
1143         SetFilePointer(file, size, NULL, FILE_BEGIN);
1144         SetEndOfFile(file);
1145     }
1146
1147     CloseHandle(file);
1148 }
1149
1150 #define create_file(name, size) create_file_data(name, name, size)
1151
1152 static void create_test_files(void)
1153 {
1154     CreateDirectoryA("msitest", NULL);
1155     create_file("msitest\\one.txt", 100);
1156     CreateDirectoryA("msitest\\first", NULL);
1157     create_file("msitest\\first\\two.txt", 100);
1158     CreateDirectoryA("msitest\\second", NULL);
1159     create_file("msitest\\second\\three.txt", 100);
1160
1161     create_file("four.txt", 100);
1162     create_file("five.txt", 100);
1163     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1164
1165     create_file("msitest\\filename", 100);
1166     create_file("msitest\\service.exe", 100);
1167
1168     DeleteFileA("four.txt");
1169     DeleteFileA("five.txt");
1170 }
1171
1172 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1173 {
1174     CHAR path[MAX_PATH];
1175
1176     lstrcpyA(path, PROG_FILES_DIR);
1177     lstrcatA(path, "\\");
1178     lstrcatA(path, rel_path);
1179
1180     if (is_file)
1181         return DeleteFileA(path);
1182     else
1183         return RemoveDirectoryA(path);
1184 }
1185
1186 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1187 {
1188     CHAR path[MAX_PATH];
1189
1190     lstrcpyA(path, COMMON_FILES_DIR);
1191     lstrcatA(path, "\\");
1192     lstrcatA(path, rel_path);
1193
1194     if (is_file)
1195         return DeleteFileA(path);
1196     else
1197         return RemoveDirectoryA(path);
1198 }
1199
1200 static void delete_test_files(void)
1201 {
1202     DeleteFileA("msitest.msi");
1203     DeleteFileA("msitest.cab");
1204     DeleteFileA("msitest\\second\\three.txt");
1205     DeleteFileA("msitest\\first\\two.txt");
1206     DeleteFileA("msitest\\one.txt");
1207     DeleteFileA("msitest\\service.exe");
1208     DeleteFileA("msitest\\filename");
1209     RemoveDirectoryA("msitest\\second");
1210     RemoveDirectoryA("msitest\\first");
1211     RemoveDirectoryA("msitest");
1212 }
1213
1214 static void write_file(const CHAR *filename, const char *data, int data_size)
1215 {
1216     DWORD size;
1217
1218     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1219                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1220
1221     WriteFile(hf, data, data_size, &size, NULL);
1222     CloseHandle(hf);
1223 }
1224
1225 static void write_msi_summary_info(MSIHANDLE db)
1226 {
1227     MSIHANDLE summary;
1228     UINT r;
1229
1230     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1232
1233     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1235
1236     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1237                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1239
1240     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1242
1243     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1245
1246     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1248
1249     /* write the summary changes back to the stream */
1250     r = MsiSummaryInfoPersist(summary);
1251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1252
1253     MsiCloseHandle(summary);
1254 }
1255
1256 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1257 {
1258     MSIHANDLE db;
1259     UINT r;
1260     int j;
1261
1262     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1263     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1264
1265     /* import the tables into the database */
1266     for (j = 0; j < num_tables; j++)
1267     {
1268         const msi_table *table = &tables[j];
1269
1270         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1271
1272         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1273         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1274
1275         DeleteFileA(table->filename);
1276     }
1277
1278     write_msi_summary_info(db);
1279
1280     r = MsiDatabaseCommit(db);
1281     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1282
1283     MsiCloseHandle(db);
1284 }
1285
1286 static void check_service_is_installed(void)
1287 {
1288     SC_HANDLE scm, service;
1289     BOOL res;
1290
1291     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1292     ok(scm != NULL, "Failed to open the SC Manager\n");
1293
1294     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1295     ok(service != NULL, "Failed to open TestService\n");
1296
1297     res = DeleteService(service);
1298     ok(res, "Failed to delete TestService\n");
1299
1300     CloseServiceHandle(service);
1301     CloseServiceHandle(scm);
1302 }
1303
1304 static void test_MsiInstallProduct(void)
1305 {
1306     UINT r;
1307     CHAR path[MAX_PATH];
1308     LONG res;
1309     HKEY hkey;
1310     DWORD num, size, type;
1311
1312     create_test_files();
1313     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1314
1315     r = MsiInstallProductA(msifile, NULL);
1316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1317
1318     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1319     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1320     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1321     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1322     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1323     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1324     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1325     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1326     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1327     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1328     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1329     ok(delete_pf("msitest", FALSE), "File not installed\n");
1330
1331     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1333
1334     size = MAX_PATH;
1335     type = REG_SZ;
1336     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1338     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1339
1340     size = MAX_PATH;
1341     type = REG_SZ;
1342     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1343     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1344
1345     size = sizeof(num);
1346     type = REG_DWORD;
1347     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1349     ok(num == 314, "Expected 314, got %d\n", num);
1350
1351     size = MAX_PATH;
1352     type = REG_SZ;
1353     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1355     ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1356
1357     check_service_is_installed();
1358
1359     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1360
1361     delete_test_files();
1362 }
1363
1364 static void test_MsiSetComponentState(void)
1365 {
1366     INSTALLSTATE installed, action;
1367     MSIHANDLE package;
1368     char path[MAX_PATH];
1369     UINT r;
1370
1371     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1372
1373     CoInitialize(NULL);
1374
1375     lstrcpy(path, CURR_DIR);
1376     lstrcat(path, "\\");
1377     lstrcat(path, msifile);
1378
1379     r = MsiOpenPackage(path, &package);
1380     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1381
1382     r = MsiDoAction(package, "CostInitialize");
1383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1384
1385     r = MsiDoAction(package, "FileCost");
1386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1387
1388     r = MsiDoAction(package, "CostFinalize");
1389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1390
1391     r = MsiGetComponentState(package, "dangler", &installed, &action);
1392     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1393     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1394     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1395
1396     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1397     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1398
1399     MsiCloseHandle(package);
1400     CoUninitialize();
1401
1402     DeleteFileA(msifile);
1403 }
1404
1405 static void test_packagecoltypes(void)
1406 {
1407     MSIHANDLE hdb, view, rec;
1408     char path[MAX_PATH];
1409     LPCSTR query;
1410     UINT r, count;
1411
1412     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1413
1414     CoInitialize(NULL);
1415
1416     lstrcpy(path, CURR_DIR);
1417     lstrcat(path, "\\");
1418     lstrcat(path, msifile);
1419
1420     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1421     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1422
1423     query = "SELECT * FROM `Media`";
1424     r = MsiDatabaseOpenView( hdb, query, &view );
1425     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1426
1427     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1428     count = MsiRecordGetFieldCount( rec );
1429     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1430     ok(count == 6, "Expected 6, got %d\n", count);
1431     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1432     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1433     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1434     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1435     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1436     ok(check_record(rec, 6, "Source"), "wrong column label\n");
1437     MsiCloseHandle(rec);
1438
1439     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1440     count = MsiRecordGetFieldCount( rec );
1441     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1442     ok(count == 6, "Expected 6, got %d\n", count);
1443     ok(check_record(rec, 1, "i2"), "wrong column label\n");
1444     ok(check_record(rec, 2, "i4"), "wrong column label\n");
1445     ok(check_record(rec, 3, "L64"), "wrong column label\n");
1446     ok(check_record(rec, 4, "S255"), "wrong column label\n");
1447     ok(check_record(rec, 5, "S32"), "wrong column label\n");
1448     ok(check_record(rec, 6, "S72"), "wrong column label\n");
1449
1450     MsiCloseHandle(rec);
1451     MsiCloseHandle(view);
1452     MsiCloseHandle(hdb);
1453     DeleteFile(msifile);
1454 }
1455
1456 static void create_cc_test_files(void)
1457 {
1458     CCAB cabParams;
1459     HFCI hfci;
1460     ERF erf;
1461     static CHAR cab_context[] = "test%d.cab";
1462     BOOL res;
1463
1464     create_file("maximus", 500);
1465     create_file("augustus", 50000);
1466     create_file("caesar", 500);
1467
1468     set_cab_parameters(&cabParams, "test1.cab", 200);
1469
1470     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1471                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1472                       get_temp_file, &cabParams, cab_context);
1473     ok(hfci != NULL, "Failed to create an FCI context\n");
1474
1475     res = add_file(hfci, "maximus", tcompTYPE_MSZIP);
1476     ok(res, "Failed to add file maximus\n");
1477
1478     res = add_file(hfci, "augustus", tcompTYPE_MSZIP);
1479     ok(res, "Failed to add file augustus\n");
1480
1481     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1482     ok(res, "Failed to flush the cabinet\n");
1483
1484     res = FCIDestroy(hfci);
1485     ok(res, "Failed to destroy the cabinet\n");
1486
1487     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1488
1489     DeleteFile("maximus");
1490     DeleteFile("augustus");
1491     DeleteFile("caesar");
1492 }
1493
1494 static void delete_cab_files(void)
1495 {
1496     SHFILEOPSTRUCT shfl;
1497     CHAR path[MAX_PATH+10];
1498
1499     lstrcpyA(path, CURR_DIR);
1500     lstrcatA(path, "\\*.cab");
1501     path[strlen(path) + 1] = '\0';
1502
1503     shfl.hwnd = NULL;
1504     shfl.wFunc = FO_DELETE;
1505     shfl.pFrom = path;
1506     shfl.pTo = NULL;
1507     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1508
1509     SHFileOperation(&shfl);
1510 }
1511
1512 static void test_continuouscabs(void)
1513 {
1514     UINT r;
1515
1516     create_cc_test_files();
1517     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1518
1519     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1520
1521     r = MsiInstallProductA(msifile, NULL);
1522     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1523     todo_wine
1524     {
1525         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1526         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1527         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1528     }
1529     ok(delete_pf("msitest", FALSE), "File not installed\n");
1530
1531     delete_cab_files();
1532     DeleteFile(msifile);
1533 }
1534
1535 static void test_caborder(void)
1536 {
1537     UINT r;
1538
1539     create_file("imperator", 100);
1540     create_file("maximus", 500);
1541     create_file("augustus", 50000);
1542     create_file("caesar", 500);
1543
1544     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1545
1546     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1547
1548     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1549     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1550     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1551
1552     r = MsiInstallProductA(msifile, NULL);
1553     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1554     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1555     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1556     todo_wine
1557     {
1558         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1559         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1560     }
1561
1562     delete_cab_files();
1563
1564     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1565     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1566     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1567
1568     r = MsiInstallProductA(msifile, NULL);
1569     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1570     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1571     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1572     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1573     todo_wine
1574     {
1575         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1576     }
1577
1578     delete_cab_files();
1579     DeleteFile(msifile);
1580
1581     create_cc_test_files();
1582     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1583
1584     r = MsiInstallProductA(msifile, NULL);
1585     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1586     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1587     ok(!delete_pf("msitest", FALSE), "File is installed\n");
1588     todo_wine
1589     {
1590         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1591         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1592     }
1593
1594     delete_cab_files();
1595     DeleteFile(msifile);
1596
1597     create_cc_test_files();
1598     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1599
1600     r = MsiInstallProductA(msifile, NULL);
1601     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1602     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1603     todo_wine
1604     {
1605         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1606         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1607         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1608     }
1609
1610     delete_cab_files();
1611     DeleteFile("imperator");
1612     DeleteFile("maximus");
1613     DeleteFile("augustus");
1614     DeleteFile("caesar");
1615     DeleteFile(msifile);
1616 }
1617
1618 static void test_mixedmedia(void)
1619 {
1620     UINT r;
1621
1622     CreateDirectoryA("msitest", NULL);
1623     create_file("msitest\\maximus", 500);
1624     create_file("msitest\\augustus", 500);
1625     create_file("caesar", 500);
1626
1627     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1628
1629     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1630
1631     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1632
1633     r = MsiInstallProductA(msifile, NULL);
1634     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1635     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1636     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1637     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1638     ok(delete_pf("msitest", FALSE), "File not installed\n");
1639
1640     /* Delete the files in the temp (current) folder */
1641     DeleteFile("msitest\\maximus");
1642     DeleteFile("msitest\\augustus");
1643     RemoveDirectory("msitest");
1644     DeleteFile("caesar");
1645     DeleteFile("test1.cab");
1646     DeleteFile(msifile);
1647 }
1648
1649 static void test_samesequence(void)
1650 {
1651     UINT r;
1652
1653     create_cc_test_files();
1654     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1655
1656     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1657
1658     r = MsiInstallProductA(msifile, NULL);
1659     todo_wine
1660     {
1661         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1662         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1663         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1664     }
1665     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1666     ok(delete_pf("msitest", FALSE), "File not installed\n");
1667
1668     delete_cab_files();
1669     DeleteFile(msifile);
1670 }
1671
1672 static void test_uiLevelFlags(void)
1673 {
1674     UINT r;
1675
1676     create_cc_test_files();
1677     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1678
1679     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1680
1681     r = MsiInstallProductA(msifile, NULL);
1682     ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1683     todo_wine
1684     {
1685         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1686         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1687     }
1688     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1689     ok(delete_pf("msitest", FALSE), "File not installed\n");
1690
1691     delete_cab_files();
1692     DeleteFile(msifile);
1693 }
1694
1695 static BOOL file_matches(LPSTR path)
1696 {
1697     CHAR buf[MAX_PATH];
1698     HANDLE file;
1699     DWORD size;
1700
1701     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1702                       NULL, OPEN_EXISTING, 0, NULL);
1703
1704     ZeroMemory(buf, MAX_PATH);
1705     ReadFile(file, buf, 15, &size, NULL);
1706     CloseHandle(file);
1707
1708     return !lstrcmp(buf, "msitest\\maximus");
1709 }
1710
1711 static void test_readonlyfile(void)
1712 {
1713     UINT r;
1714     DWORD size;
1715     HANDLE file;
1716     CHAR path[MAX_PATH];
1717
1718     CreateDirectoryA("msitest", NULL);
1719     create_file("msitest\\maximus", 500);
1720     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1721
1722     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1723
1724     lstrcpy(path, PROG_FILES_DIR);
1725     lstrcat(path, "\\msitest");
1726     CreateDirectory(path, NULL);
1727
1728     lstrcat(path, "\\maximus");
1729     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1730                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1731
1732     WriteFile(file, "readonlyfile", 20, &size, NULL);
1733     CloseHandle(file);
1734
1735     r = MsiInstallProductA(msifile, NULL);
1736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1737     ok(file_matches(path), "Expected file to be overwritten\n");
1738     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1739     ok(delete_pf("msitest", FALSE), "File not installed\n");
1740
1741     /* Delete the files in the temp (current) folder */
1742     DeleteFile("msitest\\maximus");
1743     RemoveDirectory("msitest");
1744     DeleteFile(msifile);
1745 }
1746
1747 static void test_setdirproperty(void)
1748 {
1749     UINT r;
1750
1751     CreateDirectoryA("msitest", NULL);
1752     create_file("msitest\\maximus", 500);
1753     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1754
1755     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1756
1757     r = MsiInstallProductA(msifile, NULL);
1758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1759     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1760     ok(delete_cf("msitest", FALSE), "File not installed\n");
1761
1762     /* Delete the files in the temp (current) folder */
1763     DeleteFile(msifile);
1764     DeleteFile("msitest\\maximus");
1765     RemoveDirectory("msitest");
1766 }
1767
1768 static void test_cabisextracted(void)
1769 {
1770     UINT r;
1771
1772     CreateDirectoryA("msitest", NULL);
1773     create_file("msitest\\gaius", 500);
1774     create_file("maximus", 500);
1775     create_file("augustus", 500);
1776     create_file("caesar", 500);
1777
1778     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1779     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1780     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1781
1782     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
1783
1784     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1785
1786     r = MsiInstallProductA(msifile, NULL);
1787     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1788     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1789     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1790     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1791     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
1792     ok(delete_pf("msitest", FALSE), "File not installed\n");
1793
1794     /* Delete the files in the temp (current) folder */
1795     delete_cab_files();
1796     DeleteFile(msifile);
1797     DeleteFile("maximus");
1798     DeleteFile("augustus");
1799     DeleteFile("caesar");
1800     DeleteFile("msitest\\gaius");
1801     RemoveDirectory("msitest");
1802 }
1803
1804 static void test_concurrentinstall(void)
1805 {
1806     UINT r;
1807     CHAR path[MAX_PATH];
1808
1809     CreateDirectoryA("msitest", NULL);
1810     CreateDirectoryA("msitest\\msitest", NULL);
1811     create_file("msitest\\maximus", 500);
1812     create_file("msitest\\msitest\\augustus", 500);
1813
1814     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
1815
1816     lstrcpyA(path, CURR_DIR);
1817     lstrcatA(path, "\\msitest\\concurrent.msi");
1818     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
1819
1820     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1821
1822     r = MsiInstallProductA(msifile, NULL);
1823     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1824     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1825     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1826     ok(delete_pf("msitest", FALSE), "File not installed\n");
1827
1828     /* Delete the files in the temp (current) folder */
1829     DeleteFile(msifile);
1830     DeleteFile(path);
1831     DeleteFile("msitest\\msitest\\augustus");
1832     DeleteFile("msitest\\maximus");
1833     RemoveDirectory("msitest\\msitest");
1834     RemoveDirectory("msitest");
1835 }
1836
1837 static void test_setpropertyfolder(void)
1838 {
1839     UINT r;
1840
1841     CreateDirectoryA("msitest", NULL);
1842     create_file("msitest\\maximus", 500);
1843
1844     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
1845
1846     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1847
1848     r = MsiInstallProductA(msifile, NULL);
1849     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1850     ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
1851     ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
1852     ok(delete_pf("msitest", FALSE), "File not installed\n");
1853
1854     /* Delete the files in the temp (current) folder */
1855     DeleteFile(msifile);
1856     DeleteFile("msitest\\maximus");
1857     RemoveDirectory("msitest");
1858 }
1859
1860 static BOOL file_exists(LPCSTR file)
1861 {
1862     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
1863 }
1864
1865 static BOOL pf_exists(LPCSTR file)
1866 {
1867     CHAR path[MAX_PATH];
1868
1869     lstrcpyA(path, PROG_FILES_DIR);
1870     lstrcatA(path, "\\");
1871     lstrcatA(path, file);
1872
1873     return file_exists(path);
1874 }
1875
1876 static void delete_pfmsitest_files(void)
1877 {
1878     SHFILEOPSTRUCT shfl;
1879     CHAR path[MAX_PATH+11];
1880
1881     lstrcpyA(path, PROG_FILES_DIR);
1882     lstrcatA(path, "\\msitest\\*");
1883     path[strlen(path) + 1] = '\0';
1884
1885     shfl.hwnd = NULL;
1886     shfl.wFunc = FO_DELETE;
1887     shfl.pFrom = path;
1888     shfl.pTo = NULL;
1889     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1890
1891     SHFileOperation(&shfl);
1892
1893     lstrcpyA(path, PROG_FILES_DIR);
1894     lstrcatA(path, "\\msitest");
1895     RemoveDirectoryA(path);
1896 }
1897
1898 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
1899 {
1900     char val[MAX_PATH];
1901     DWORD size, type;
1902     LONG res;
1903
1904     size = MAX_PATH;
1905     val[0] = '\0';
1906     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
1907
1908     if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
1909     {
1910         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
1911         return;
1912     }
1913
1914     if (!expected)
1915         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
1916     else
1917     {
1918         if (bcase)
1919             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
1920         else
1921             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
1922     }
1923 }
1924
1925 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
1926 {
1927     DWORD val, size, type;
1928     LONG res;
1929
1930     size = sizeof(DWORD);
1931     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
1932
1933     if (res != ERROR_SUCCESS || type != REG_DWORD)
1934     {
1935         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
1936         return;
1937     }
1938
1939     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
1940 }
1941
1942 #define CHECK_REG_STR(prodkey, name, expected) \
1943     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
1944
1945 #define CHECK_REG_ISTR(prodkey, name, expected) \
1946     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
1947
1948 #define CHECK_REG_DWORD(prodkey, name, expected) \
1949     check_reg_dword(prodkey, name, expected, __LINE__);
1950
1951 static void get_date_str(LPSTR date)
1952 {
1953     SYSTEMTIME systime;
1954
1955     static const char date_fmt[] = "%d%02d%02d";
1956     GetLocalTime(&systime);
1957     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
1958 }
1959
1960 static void test_publish(void)
1961 {
1962     UINT r;
1963     LONG res;
1964     HKEY uninstall, prodkey;
1965     INSTALLSTATE state;
1966     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
1967     char date[MAX_PATH];
1968     char temp[MAX_PATH];
1969
1970     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
1971
1972     get_date_str(date);
1973     GetTempPath(MAX_PATH, temp);
1974
1975     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
1976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1977
1978     CreateDirectoryA("msitest", NULL);
1979     create_file("msitest\\maximus", 500);
1980
1981     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
1982
1983     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1984
1985     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1986     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, 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     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1997     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1998
1999     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2000     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2001
2002     /* nothing published */
2003     r = MsiInstallProductA(msifile, NULL);
2004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2005     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2006     ok(pf_exists("msitest"), "File not installed\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     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2023     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2024
2025     /* install again */
2026     r = MsiInstallProductA(msifile, NULL);
2027     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2028     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2029     ok(pf_exists("msitest"), "File not installed\n");
2030
2031     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2032     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2033
2034     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2035     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2036
2037     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2038     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2039
2040     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2041                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2042     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2043     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2044
2045     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2046     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2047
2048     /* try to uninstall */
2049     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2050     todo_wine
2051     {
2052         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2053     }
2054     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2055     ok(pf_exists("msitest"), "File deleted\n");
2056
2057     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2058     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2059
2060     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2061     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2062
2063     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2064     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2065
2066     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2067                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2068     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2069     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2070
2071     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2072     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2073
2074     /* PublishProduct */
2075     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=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_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2082
2083     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2084     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2085
2086     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2087                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2088     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2089     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2090
2091     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2092     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2093
2094     /* try to uninstall after PublishProduct */
2095     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2096     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2097     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2098     ok(pf_exists("msitest"), "File deleted\n");
2099
2100     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2101     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2102
2103     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2104     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2105
2106     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2107     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2108
2109     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2110                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2111     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2112     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2113
2114     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2115     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2116
2117     /* RegisterProduct */
2118     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2119     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2120     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2121     ok(pf_exists("msitest"), "File not installed\n");
2122
2123     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2124     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2125
2126     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2127     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2128
2129     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2130                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2131     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2132     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2133
2134     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2136
2137     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2138     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2139     CHECK_REG_STR(prodkey, "InstallDate", date);
2140     CHECK_REG_STR(prodkey, "InstallSource", temp);
2141     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2142     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2143     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2144     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2145     CHECK_REG_STR(prodkey, "Comments", NULL);
2146     CHECK_REG_STR(prodkey, "Contact", NULL);
2147     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2148     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2149     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2150     CHECK_REG_STR(prodkey, "Readme", NULL);
2151     CHECK_REG_STR(prodkey, "Size", NULL);
2152     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2153     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2154     CHECK_REG_DWORD(prodkey, "Language", 1033);
2155     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2156     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2157     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2158     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2159     todo_wine
2160     {
2161         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2162     }
2163
2164     RegCloseKey(prodkey);
2165
2166     /* complete uninstall */
2167     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2168     todo_wine
2169     {
2170         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2171     }
2172     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2173     ok(pf_exists("msitest"), "File deleted\n");
2174
2175     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2176     todo_wine
2177     {
2178         ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2179     }
2180
2181     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2182     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2183
2184     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2185     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2186
2187     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2188                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2189     todo_wine
2190     {
2191         ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2192     }
2193     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2194
2195     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2197
2198     todo_wine
2199     {
2200         CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2201         CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2202         CHECK_REG_STR(prodkey, "InstallDate", date);
2203         CHECK_REG_STR(prodkey, "InstallSource", temp);
2204         CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2205         CHECK_REG_STR(prodkey, "Publisher", "Wine");
2206         CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2207         CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2208         CHECK_REG_STR(prodkey, "Comments", NULL);
2209         CHECK_REG_STR(prodkey, "Contact", NULL);
2210         CHECK_REG_STR(prodkey, "HelpLink", NULL);
2211         CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2212         CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2213         CHECK_REG_STR(prodkey, "Readme", NULL);
2214         CHECK_REG_STR(prodkey, "Size", NULL);
2215         CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2216         CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2217         CHECK_REG_DWORD(prodkey, "Language", 1033);
2218         CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2219         CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2220         CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2221         CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2222         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2223     }
2224
2225     RegCloseKey(prodkey);
2226
2227     /* PublishProduct and RegisterProduct */
2228     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
2229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2230     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2231     ok(pf_exists("msitest"), "File not installed\n");
2232
2233     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2234     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2235
2236     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2237     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2238
2239     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2240     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2241
2242     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2243                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2244     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2245     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2246
2247     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2249
2250     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2251     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2252     CHECK_REG_STR(prodkey, "InstallDate", date);
2253     CHECK_REG_STR(prodkey, "InstallSource", temp);
2254     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2255     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2256     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2257     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2258     CHECK_REG_STR(prodkey, "Comments", NULL);
2259     CHECK_REG_STR(prodkey, "Contact", NULL);
2260     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2261     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2262     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2263     CHECK_REG_STR(prodkey, "Readme", NULL);
2264     CHECK_REG_STR(prodkey, "Size", NULL);
2265     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2266     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2267     CHECK_REG_DWORD(prodkey, "Language", 1033);
2268     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2269     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2270     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2271     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2272     todo_wine
2273     {
2274         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2275     }
2276
2277     RegCloseKey(prodkey);
2278
2279     /* try it again */
2280     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
2281     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2282     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2283     ok(pf_exists("msitest"), "File not installed\n");
2284
2285     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2286     todo_wine
2287     {
2288         ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2289     }
2290
2291     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2292     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2293
2294     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2295     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2296
2297     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2298                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2299     todo_wine
2300     {
2301         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2302     }
2303     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2304
2305     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2306     todo_wine
2307     {
2308         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2309     }
2310
2311     /* uninstall has a problem with this */
2312     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2313     todo_wine
2314     {
2315         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2316     }
2317     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2318     ok(pf_exists("msitest"), "File deleted\n");
2319
2320     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2321     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2322
2323     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2324     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2325
2326     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2327                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2328     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2329     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2330
2331     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2332     todo_wine
2333     {
2334         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2335     }
2336
2337     /* PublishProduct and RegisterProduct and ProcessComponents */
2338     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
2339     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2340     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2341     ok(pf_exists("msitest"), "File not installed\n");
2342
2343     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2344     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2345
2346     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2347     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2348
2349     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2350     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2351
2352     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2353                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2355     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2356
2357     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2359
2360     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2361     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2362     CHECK_REG_STR(prodkey, "InstallDate", date);
2363     CHECK_REG_STR(prodkey, "InstallSource", temp);
2364     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2365     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2366     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2367     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2368     CHECK_REG_STR(prodkey, "Comments", NULL);
2369     CHECK_REG_STR(prodkey, "Contact", NULL);
2370     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2371     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2372     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2373     CHECK_REG_STR(prodkey, "Readme", NULL);
2374     CHECK_REG_STR(prodkey, "Size", NULL);
2375     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2376     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2377     CHECK_REG_DWORD(prodkey, "Language", 1033);
2378     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2379     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2380     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2381     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2382     todo_wine
2383     {
2384         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2385     }
2386
2387     RegCloseKey(prodkey);
2388
2389     /* complete uninstall */
2390     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2391     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2392     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2393     ok(pf_exists("msitest"), "File deleted\n");
2394
2395     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2396     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2397
2398     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2399     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2400
2401     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2402     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2403
2404     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2405                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2406     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2407     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2408
2409     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2410     todo_wine
2411     {
2412         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2413     }
2414
2415     /* PublishProduct, RegisterProduct, ProcessComponents, PublishFeatures */
2416     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1 PUBLISH_FEATURES=1");
2417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2418     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2419     ok(pf_exists("msitest"), "File not installed\n");
2420
2421     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2422     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2423
2424     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2425     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2426
2427     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2428     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2429
2430     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2431                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2433     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2434
2435     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2437
2438     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2439     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2440     CHECK_REG_STR(prodkey, "InstallDate", date);
2441     CHECK_REG_STR(prodkey, "InstallSource", temp);
2442     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2443     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2444     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2445     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2446     CHECK_REG_STR(prodkey, "Comments", NULL);
2447     CHECK_REG_STR(prodkey, "Contact", NULL);
2448     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2449     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2450     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2451     CHECK_REG_STR(prodkey, "Readme", NULL);
2452     CHECK_REG_STR(prodkey, "Size", NULL);
2453     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2454     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2455     CHECK_REG_DWORD(prodkey, "Language", 1033);
2456     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2457     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2458     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2459     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2460     todo_wine
2461     {
2462         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2463     }
2464
2465     RegCloseKey(prodkey);
2466
2467     /* complete uninstall */
2468     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2470     todo_wine
2471     {
2472         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2473         ok(!pf_exists("msitest"), "File deleted\n");
2474     }
2475
2476     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2477     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2478
2479     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2480     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2481
2482     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2483     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2484
2485     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2486                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2487     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2488     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2489
2490     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2491     todo_wine
2492     {
2493         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2494     }
2495
2496     /* complete install */
2497     r = MsiInstallProductA(msifile, "FULL=1");
2498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2499     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2500     ok(pf_exists("msitest"), "File not installed\n");
2501
2502     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2503     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2504
2505     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2506     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2507
2508     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2509     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2510
2511     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2512                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2514     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2515
2516     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2518
2519     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2520     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2521     CHECK_REG_STR(prodkey, "InstallDate", date);
2522     CHECK_REG_STR(prodkey, "InstallSource", temp);
2523     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2524     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2525     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2526     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2527     CHECK_REG_STR(prodkey, "Comments", NULL);
2528     CHECK_REG_STR(prodkey, "Contact", NULL);
2529     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2530     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2531     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2532     CHECK_REG_STR(prodkey, "Readme", NULL);
2533     CHECK_REG_STR(prodkey, "Size", NULL);
2534     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2535     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2536     CHECK_REG_DWORD(prodkey, "Language", 1033);
2537     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2538     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2539     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2540     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2541     todo_wine
2542     {
2543         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2544     }
2545
2546     RegCloseKey(prodkey);
2547
2548     /* no UnpublishFeatures */
2549     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2551     todo_wine
2552     {
2553         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2554         ok(!pf_exists("msitest"), "File deleted\n");
2555     }
2556
2557     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2558     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2559
2560     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2561     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2562
2563     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2564     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2565
2566     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2567                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2568     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2569     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2570
2571     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2572     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2573
2574     /* complete install */
2575     r = MsiInstallProductA(msifile, "FULL=1");
2576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2577     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2578     ok(pf_exists("msitest"), "File not installed\n");
2579
2580     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2581     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2582
2583     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2584     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2585
2586     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2587     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2588
2589     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2590                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2591     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2592     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2593
2594     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2596
2597     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2598     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2599     CHECK_REG_STR(prodkey, "InstallDate", date);
2600     CHECK_REG_STR(prodkey, "InstallSource", temp);
2601     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2602     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2603     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2604     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2605     CHECK_REG_STR(prodkey, "Comments", NULL);
2606     CHECK_REG_STR(prodkey, "Contact", NULL);
2607     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2608     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2609     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2610     CHECK_REG_STR(prodkey, "Readme", NULL);
2611     CHECK_REG_STR(prodkey, "Size", NULL);
2612     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2613     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2614     CHECK_REG_DWORD(prodkey, "Language", 1033);
2615     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2616     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2617     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2618     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2619     todo_wine
2620     {
2621         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2622     }
2623
2624     RegCloseKey(prodkey);
2625
2626     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
2627     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
2628     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2629     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2630     ok(pf_exists("msitest"), "File deleted\n");
2631
2632     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2633     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2634
2635     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2636     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2637
2638     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2639     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2640
2641     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2642                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2643     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2644     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2645
2646     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2648
2649     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2650     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2651     CHECK_REG_STR(prodkey, "InstallDate", date);
2652     CHECK_REG_STR(prodkey, "InstallSource", temp);
2653     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2654     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2655     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2656     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2657     CHECK_REG_STR(prodkey, "Comments", NULL);
2658     CHECK_REG_STR(prodkey, "Contact", NULL);
2659     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2660     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2661     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2662     CHECK_REG_STR(prodkey, "Readme", NULL);
2663     CHECK_REG_STR(prodkey, "Size", NULL);
2664     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2665     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2666     CHECK_REG_DWORD(prodkey, "Language", 1033);
2667     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2668     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2669     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2670     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2671     todo_wine
2672     {
2673         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2674     }
2675
2676     RegCloseKey(prodkey);
2677
2678     /* complete install */
2679     r = MsiInstallProductA(msifile, "FULL=1");
2680     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2681     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2682     ok(pf_exists("msitest"), "File not installed\n");
2683
2684     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2685     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2686
2687     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2688     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2689
2690     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2691     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2692
2693     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2694                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2695     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2696     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2697
2698     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2700
2701     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2702     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2703     CHECK_REG_STR(prodkey, "InstallDate", date);
2704     CHECK_REG_STR(prodkey, "InstallSource", temp);
2705     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2706     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2707     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2708     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2709     CHECK_REG_STR(prodkey, "Comments", NULL);
2710     CHECK_REG_STR(prodkey, "Contact", NULL);
2711     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2712     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2713     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2714     CHECK_REG_STR(prodkey, "Readme", NULL);
2715     CHECK_REG_STR(prodkey, "Size", NULL);
2716     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2717     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2718     CHECK_REG_DWORD(prodkey, "Language", 1033);
2719     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2720     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2721     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2722     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2723     todo_wine
2724     {
2725         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2726     }
2727
2728     RegCloseKey(prodkey);
2729
2730     /* UnpublishFeatures, both features removed */
2731     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
2732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2733     todo_wine
2734     {
2735         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2736         ok(!pf_exists("msitest"), "File not deleted\n");
2737     }
2738
2739     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2740     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2741
2742     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2743     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2744
2745     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2746     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2747
2748     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2749                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2750     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2751     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2752
2753     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2754     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2755
2756     /* complete install */
2757     r = MsiInstallProductA(msifile, "FULL=1");
2758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2759     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2760     ok(pf_exists("msitest"), "File not installed\n");
2761
2762     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2763     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2764
2765     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2766     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2767
2768     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2769     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2770
2771     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2772                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2773     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2774     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2775
2776     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2778
2779     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2780     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2781     CHECK_REG_STR(prodkey, "InstallDate", date);
2782     CHECK_REG_STR(prodkey, "InstallSource", temp);
2783     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2784     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2785     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2786     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2787     CHECK_REG_STR(prodkey, "Comments", NULL);
2788     CHECK_REG_STR(prodkey, "Contact", NULL);
2789     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2790     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2791     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2792     CHECK_REG_STR(prodkey, "Readme", NULL);
2793     CHECK_REG_STR(prodkey, "Size", NULL);
2794     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2795     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2796     CHECK_REG_DWORD(prodkey, "Language", 1033);
2797     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2798     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2799     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2800     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2801     todo_wine
2802     {
2803         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2804     }
2805
2806     RegCloseKey(prodkey);
2807
2808     /* complete uninstall */
2809     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2811     todo_wine
2812     {
2813         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2814         ok(!pf_exists("msitest"), "File not deleted\n");
2815     }
2816
2817     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2818     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2819
2820     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2821     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2822
2823     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2824     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2825
2826     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2827                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2828     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2829     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2830
2831     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2832     todo_wine
2833     {
2834         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2835     }
2836
2837     /* make sure 'Program Files\msitest' is removed */
2838     delete_pfmsitest_files();
2839
2840     RegCloseKey(uninstall);
2841     DeleteFile(msifile);
2842     DeleteFile("msitest\\maximus");
2843     RemoveDirectory("msitest");
2844 }
2845
2846 static void test_publishsourcelist(void)
2847 {
2848     UINT r;
2849     DWORD size;
2850     CHAR value[MAX_PATH];
2851     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2852
2853     CreateDirectoryA("msitest", NULL);
2854     create_file("msitest\\maximus", 500);
2855
2856     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2857
2858     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2859
2860     r = MsiInstallProductA(msifile, NULL);
2861     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2862     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2863     ok(pf_exists("msitest"), "File not installed\n");
2864
2865     /* nothing published */
2866     size = 0xdeadbeef;
2867     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2868                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2869     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2870     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2871
2872     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2873     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2874     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2875     ok(pf_exists("msitest"), "File not installed\n");
2876
2877     /* after RegisterProduct */
2878     size = 0xdeadbeef;
2879     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2880                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2881     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2882     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2883
2884     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
2885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2886     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2887     ok(pf_exists("msitest"), "File not installed\n");
2888
2889     /* after ProcessComponents */
2890     size = 0xdeadbeef;
2891     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2892                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2893     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2894     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2895
2896     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2897     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2898     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2899     ok(pf_exists("msitest"), "File not installed\n");
2900
2901     /* after PublishFeatures */
2902     size = 0xdeadbeef;
2903     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2904                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2905     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2906     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2907
2908     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2910     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2911     ok(pf_exists("msitest"), "File not installed\n");
2912
2913     /* after PublishProduct */
2914     size = MAX_PATH;
2915     lstrcpyA(value, "aaa");
2916     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2917                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
2918     todo_wine
2919     {
2920         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2921         ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
2922         ok(size == 11, "Expected 11, got %d\n", size);
2923     }
2924
2925     /* complete uninstall */
2926     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2927     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2928     todo_wine
2929     {
2930         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2931         ok(!pf_exists("msitest"), "File not deleted\n");
2932     }
2933
2934     /* make sure 'Program Files\msitest' is removed */
2935     delete_pfmsitest_files();
2936
2937     DeleteFile(msifile);
2938     DeleteFile("msitest\\maximus");
2939     RemoveDirectory("msitest");
2940 }
2941
2942 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
2943 {
2944     MSIHANDLE hview = 0;
2945     UINT r;
2946
2947     r = MsiDatabaseOpenView(hdb, query, &hview);
2948     if(r != ERROR_SUCCESS)
2949         return r;
2950
2951     r = MsiViewExecute(hview, hrec);
2952     if(r == ERROR_SUCCESS)
2953         r = MsiViewClose(hview);
2954     MsiCloseHandle(hview);
2955     return r;
2956 }
2957
2958 static void set_transform_summary_info(void)
2959 {
2960     UINT r;
2961     MSIHANDLE suminfo = 0;
2962
2963     /* build summmary info */
2964     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
2965     todo_wine
2966     {
2967         ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
2968     }
2969
2970     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2971     todo_wine
2972     {
2973         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2974     }
2975
2976     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2977                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2978                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2979                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
2980     todo_wine
2981     {
2982         ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
2983     }
2984
2985     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
2986     todo_wine
2987     {
2988         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2989     }
2990
2991     r = MsiSummaryInfoPersist(suminfo);
2992     todo_wine
2993     {
2994         ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
2995     }
2996
2997     r = MsiCloseHandle(suminfo);
2998     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
2999 }
3000
3001 static void generate_transform(void)
3002 {
3003     MSIHANDLE hdb1, hdb2;
3004     LPCSTR query;
3005     UINT r;
3006
3007     /* start with two identical databases */
3008     CopyFile(msifile, msifile2, FALSE);
3009
3010     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
3011     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3012
3013     r = MsiDatabaseCommit(hdb1);
3014     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
3015
3016     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
3017     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3018
3019     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
3020     r = run_query(hdb1, 0, query);
3021     ok(r == ERROR_SUCCESS, "failed to add property\n");
3022
3023     /* database needs to be committed */
3024     MsiDatabaseCommit(hdb1);
3025
3026     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
3027     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
3028
3029 #if 0  /* not implemented in wine yet */
3030     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
3031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3032 #endif
3033
3034     MsiCloseHandle(hdb1);
3035     MsiCloseHandle(hdb2);
3036 }
3037
3038 /* data for generating a transform */
3039
3040 /* tables transform names - encoded as they would be in an msi database file */
3041 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3042 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3043 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3044
3045 /* data in each table */
3046 static const char data1[] = /* _StringData */
3047     "propval";  /* all the strings squashed together */
3048
3049 static const WCHAR data2[] = { /* _StringPool */
3050 /*  len, refs */
3051     0,   0,    /* string 0 ''     */
3052     4,   1,    /* string 1 'prop' */
3053     3,   1,    /* string 2 'val'  */
3054 };
3055
3056 static const WCHAR data3[] = { /* Property */
3057     0x0201, 0x0001, 0x0002,
3058 };
3059
3060 static const struct {
3061     LPCWSTR name;
3062     const void *data;
3063     DWORD size;
3064 } table_transform_data[] =
3065 {
3066     { name1, data1, sizeof data1 - 1 },
3067     { name2, data2, sizeof data2 },
3068     { name3, data3, sizeof data3 },
3069 };
3070
3071 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
3072
3073 static void generate_transform_manual(void)
3074 {
3075     IStorage *stg = NULL;
3076     IStream *stm;
3077     WCHAR name[0x20];
3078     HRESULT r;
3079     DWORD i, count;
3080     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
3081
3082     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
3083
3084     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
3085
3086     r = StgCreateDocfile(name, mode, 0, &stg);
3087     ok(r == S_OK, "failed to create storage\n");
3088     if (!stg)
3089         return;
3090
3091     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
3092     ok(r == S_OK, "failed to set storage type\n");
3093
3094     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
3095     {
3096         r = IStorage_CreateStream(stg, table_transform_data[i].name,
3097                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3098         if (FAILED(r))
3099         {
3100             ok(0, "failed to create stream %08x\n", r);
3101             continue;
3102         }
3103
3104         r = IStream_Write(stm, table_transform_data[i].data,
3105                           table_transform_data[i].size, &count);
3106         if (FAILED(r) || count != table_transform_data[i].size)
3107             ok(0, "failed to write stream\n");
3108         IStream_Release(stm);
3109     }
3110
3111     IStorage_Release(stg);
3112
3113     set_transform_summary_info();
3114 }
3115
3116 static void test_transformprop(void)
3117 {
3118     UINT r;
3119
3120     CreateDirectoryA("msitest", NULL);
3121     create_file("msitest\\augustus", 500);
3122
3123     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
3124
3125     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3126
3127     r = MsiInstallProductA(msifile, NULL);
3128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3129     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3130     ok(!delete_pf("msitest", FALSE), "File installed\n");
3131
3132     if (0)
3133         generate_transform();
3134     else
3135         generate_transform_manual();
3136
3137     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
3138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3139     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3140     ok(delete_pf("msitest", FALSE), "File not installed\n");
3141
3142     /* Delete the files in the temp (current) folder */
3143     DeleteFile(msifile);
3144     DeleteFile(msifile2);
3145     DeleteFile(mstfile);
3146     DeleteFile("msitest\\augustus");
3147     RemoveDirectory("msitest");
3148 }
3149
3150 static void test_currentworkingdir(void)
3151 {
3152     UINT r;
3153     CHAR path[MAX_PATH];
3154     LPSTR ptr, ptr2;
3155
3156     CreateDirectoryA("msitest", NULL);
3157     create_file("msitest\\augustus", 500);
3158
3159     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
3160
3161     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3162
3163     CreateDirectoryA("diffdir", NULL);
3164     SetCurrentDirectoryA("diffdir");
3165
3166     sprintf(path, "..\\%s", msifile);
3167     r = MsiInstallProductA(path, NULL);
3168     todo_wine
3169     {
3170         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
3171         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3172         ok(!delete_pf("msitest", FALSE), "File installed\n");
3173     }
3174
3175     sprintf(path, "%s\\%s", CURR_DIR, msifile);
3176     r = MsiInstallProductA(path, NULL);
3177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3178     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3179     ok(delete_pf("msitest", FALSE), "File not installed\n");
3180
3181     lstrcpyA(path, CURR_DIR);
3182     if (path[lstrlenA(path) - 1] != '\\')
3183         lstrcatA(path, "\\");
3184     lstrcatA(path, "msitest.msi");
3185
3186     ptr2 = strrchr(path, '\\');
3187     *ptr2 = '\0';
3188     ptr = strrchr(path, '\\');
3189     *ptr2 = '\\';
3190     *(ptr++) = '\0';
3191
3192     SetCurrentDirectoryA(path);
3193
3194     r = MsiInstallProductA(ptr, NULL);
3195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3196     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3197     ok(delete_pf("msitest", FALSE), "File not installed\n");
3198
3199     SetCurrentDirectoryA(CURR_DIR);
3200
3201     DeleteFile(msifile);
3202     DeleteFile("msitest\\augustus");
3203     RemoveDirectory("msitest");
3204     RemoveDirectory("diffdir");
3205 }
3206
3207 static void set_admin_summary_info(const CHAR *name)
3208 {
3209     MSIHANDLE db, summary;
3210     UINT r;
3211
3212     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
3213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3214
3215     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
3216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3217
3218     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
3219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3220
3221     /* write the summary changes back to the stream */
3222     r = MsiSummaryInfoPersist(summary);
3223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3224
3225     MsiCloseHandle(summary);
3226
3227     r = MsiDatabaseCommit(db);
3228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3229
3230     MsiCloseHandle(db);
3231 }
3232
3233 static void test_admin(void)
3234 {
3235     UINT r;
3236
3237     CreateDirectoryA("msitest", NULL);
3238     create_file("msitest\\augustus", 500);
3239
3240     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
3241     set_admin_summary_info(msifile);
3242
3243     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3244
3245     r = MsiInstallProductA(msifile, NULL);
3246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3247     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3248     ok(!delete_pf("msitest", FALSE), "File installed\n");
3249     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
3250     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
3251
3252     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
3253     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3254     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3255     ok(!delete_pf("msitest", FALSE), "File installed\n");
3256     todo_wine
3257     {
3258         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
3259         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
3260     }
3261
3262     DeleteFile(msifile);
3263     DeleteFile("msitest\\augustus");
3264     RemoveDirectory("msitest");
3265 }
3266
3267 static void set_admin_property_stream(LPCSTR file)
3268 {
3269     IStorage *stg;
3270     IStream *stm;
3271     WCHAR fileW[MAX_PATH];
3272     HRESULT hr;
3273     DWORD count;
3274     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
3275
3276     /* AdminProperties */
3277     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
3278     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
3279
3280     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
3281
3282     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
3283     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3284     if (!stg)
3285         return;
3286
3287     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3288     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3289
3290     hr = IStream_Write(stm, data, sizeof(data), &count);
3291     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3292
3293     IStream_Release(stm);
3294     IStorage_Release(stg);
3295 }
3296
3297 static void test_adminprops(void)
3298 {
3299     UINT r;
3300
3301     CreateDirectoryA("msitest", NULL);
3302     create_file("msitest\\augustus", 500);
3303
3304     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
3305     set_admin_summary_info(msifile);
3306     set_admin_property_stream(msifile);
3307
3308     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3309
3310     r = MsiInstallProductA(msifile, NULL);
3311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3312     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
3313     ok(delete_pf("msitest", FALSE), "File installed\n");
3314
3315     DeleteFile(msifile);
3316     DeleteFile("msitest\\augustus");
3317     RemoveDirectory("msitest");
3318 }
3319
3320 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
3321 {
3322     CHAR path[MAX_PATH];
3323
3324     lstrcpyA(path, PROG_FILES_DIR);
3325     lstrcatA(path, "\\");
3326     lstrcatA(path, file);
3327
3328     if (is_file)
3329         create_file_data(path, data, 500);
3330     else
3331         CreateDirectoryA(path, NULL);
3332 }
3333
3334 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
3335
3336 static void test_removefiles(void)
3337 {
3338     UINT r;
3339
3340     CreateDirectoryA("msitest", NULL);
3341     create_file("msitest\\hydrogen", 500);
3342     create_file("msitest\\helium", 500);
3343     create_file("msitest\\lithium", 500);
3344
3345     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
3346
3347     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3348
3349     r = MsiInstallProductA(msifile, NULL);
3350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3351     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
3352     ok(!pf_exists("msitest\\helium"), "File installed\n");
3353     ok(pf_exists("msitest\\lithium"), "File not installed\n");
3354     ok(pf_exists("msitest"), "File not installed\n");
3355
3356     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3358     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
3359     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
3360     todo_wine
3361     {
3362         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
3363         ok(delete_pf("msitest", FALSE), "File deleted\n");
3364     }
3365
3366     create_pf("msitest", FALSE);
3367     create_pf("msitest\\hydrogen", TRUE);
3368     create_pf("msitest\\helium", TRUE);
3369     create_pf("msitest\\lithium", TRUE);
3370
3371     r = MsiInstallProductA(msifile, NULL);
3372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3373     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
3374     ok(pf_exists("msitest\\helium"), "File not installed\n");
3375     ok(pf_exists("msitest\\lithium"), "File not installed\n");
3376     ok(pf_exists("msitest"), "File not installed\n");
3377
3378     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3379     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3380     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
3381     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
3382     todo_wine
3383     {
3384         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
3385         ok(delete_pf("msitest", FALSE), "File deleted\n");
3386     }
3387
3388     create_pf("msitest", FALSE);
3389     create_pf("msitest\\furlong", TRUE);
3390     create_pf("msitest\\firkin", TRUE);
3391     create_pf("msitest\\fortnight", TRUE);
3392     create_pf("msitest\\becquerel", TRUE);
3393     create_pf("msitest\\dioptre", TRUE);
3394     create_pf("msitest\\attoparsec", TRUE);
3395     create_pf("msitest\\storeys", TRUE);
3396     create_pf("msitest\\block", TRUE);
3397     create_pf("msitest\\siriometer", TRUE);
3398
3399     r = MsiInstallProductA(msifile, NULL);
3400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3401     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
3402     ok(!pf_exists("msitest\\helium"), "File installed\n");
3403     ok(pf_exists("msitest\\lithium"), "File not installed\n");
3404     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
3405     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
3406     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
3407     ok(pf_exists("msitest"), "File not installed\n");
3408     todo_wine
3409     {
3410         ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
3411         ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
3412         ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
3413         ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
3414         ok(!pf_exists("msitest\\block"), "File not deleted\n");
3415         ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
3416     }
3417
3418     create_pf("msitest\\furlong", TRUE);
3419     create_pf("msitest\\firkin", TRUE);
3420     create_pf("msitest\\fortnight", TRUE);
3421     create_pf("msitest\\storeys", TRUE);
3422     create_pf("msitest\\block", TRUE);
3423     create_pf("msitest\\siriometer", TRUE);
3424
3425     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3426     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3427     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
3428     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
3429     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
3430     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
3431     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
3432     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
3433     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
3434     todo_wine
3435     {
3436         ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
3437         ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
3438         ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
3439         ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
3440         ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
3441     }
3442     ok(delete_pf("msitest", FALSE), "File deleted\n");
3443
3444     DeleteFile(msifile);
3445     DeleteFile("msitest\\hydrogen");
3446     DeleteFile("msitest\\helium");
3447     DeleteFile("msitest\\lithium");
3448     RemoveDirectory("msitest");
3449 }
3450
3451 static void test_movefiles(void)
3452 {
3453     UINT r;
3454     char props[MAX_PATH];
3455
3456     CreateDirectoryA("msitest", NULL);
3457     create_file("msitest\\augustus", 100);
3458     create_file("cameroon", 100);
3459     create_file("djibouti", 100);
3460     create_file("egypt", 100);
3461     create_file("finland", 100);
3462     create_file("gambai", 100);
3463     create_file("honduras", 100);
3464     create_file("msitest\\india", 100);
3465     create_file("japan", 100);
3466     create_file("kenya", 100);
3467     CreateDirectoryA("latvia", NULL);
3468     create_file("nauru", 100);
3469     create_file("apple", 100);
3470     create_file("application", 100);
3471     create_file("ape", 100);
3472     create_file("foo", 100);
3473     create_file("fao", 100);
3474     create_file("fbod", 100);
3475     create_file("budding", 100);
3476     create_file("buddy", 100);
3477     create_file("bud", 100);
3478     create_file("bar", 100);
3479     create_file("bur", 100);
3480     create_file("bird", 100);
3481
3482     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
3483
3484     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3485     MsiEnableLog(INSTALLLOGMODE_VERBOSE | INSTALLLOGMODE_EXTRADEBUG, "log.txt", 0);
3486
3487     /* if the source or dest property is not a full path,
3488      * windows tries to access it as a network resource
3489      */
3490
3491     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
3492             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
3493             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
3494
3495     r = MsiInstallProductA(msifile, props);
3496     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3497     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3498     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
3499     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
3500     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
3501     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
3502     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
3503     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
3504     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
3505     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
3506     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
3507     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
3508     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
3509     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
3510     ok(!delete_pf("msitest\\apple", TRUE), "File should not exist\n");
3511     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
3512     ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
3513     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
3514     ok(delete_pf("msitest\\foo", TRUE), "File not moved\n");
3515     ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
3516     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
3517     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
3518     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
3519     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
3520     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
3521     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
3522     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
3523     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
3524     ok(delete_pf("msitest", FALSE), "File not installed\n");
3525     ok(DeleteFileA("cameroon"), "File moved\n");
3526     ok(!DeleteFileA("djibouti"), "File not moved\n");
3527     ok(DeleteFileA("egypt"), "File moved\n");
3528     ok(DeleteFileA("finland"), "File moved\n");
3529     ok(DeleteFileA("gambai"), "File moved\n");
3530     ok(!DeleteFileA("honduras"), "File not moved\n");
3531     ok(DeleteFileA("msitest\\india"), "File moved\n");
3532     ok(DeleteFileA("japan"), "File moved\n");
3533     ok(!DeleteFileA("kenya"), "File not moved\n");
3534     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
3535     ok(!DeleteFileA("nauru"), "File not moved\n");
3536     ok(!DeleteFileA("apple"), "File not moved\n");
3537     ok(!DeleteFileA("application"), "File not moved\n");
3538     ok(DeleteFileA("ape"), "File moved\n");
3539     ok(!DeleteFileA("foo"), "File not moved\n");
3540     ok(!DeleteFileA("fao"), "File not moved\n");
3541     ok(DeleteFileA("fbod"), "File moved\n");
3542     ok(!DeleteFileA("budding"), "File not moved\n");
3543     ok(!DeleteFileA("buddy"), "File not moved\n");
3544     ok(DeleteFileA("bud"), "File moved\n");
3545     ok(!DeleteFileA("bar"), "File not moved\n");
3546     ok(!DeleteFileA("bur"), "File not moved\n");
3547     ok(DeleteFileA("bird"), "File moved\n");
3548
3549     DeleteFile("msitest\\augustus");
3550     RemoveDirectory("msitest");
3551     DeleteFile(msifile);
3552 }
3553
3554 static void test_missingcab(void)
3555 {
3556     UINT r;
3557
3558     CreateDirectoryA("msitest", NULL);
3559     create_file("msitest\\augustus", 500);
3560     create_file("maximus", 500);
3561
3562     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
3563
3564     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3565
3566     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3567
3568     create_pf("msitest", FALSE);
3569     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
3570
3571     r = MsiInstallProductA(msifile, NULL);
3572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3573     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3574     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3575     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3576     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
3577     ok(delete_pf("msitest", FALSE), "File not installed\n");
3578
3579     create_pf("msitest", FALSE);
3580     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
3581     create_pf("msitest\\gaius", TRUE);
3582
3583     r = MsiInstallProductA(msifile, "GAIUS=1");
3584     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3585     todo_wine
3586     {
3587         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
3588         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3589     }
3590     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
3591     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
3592     ok(delete_pf("msitest", FALSE), "File not installed\n");
3593
3594     DeleteFile("msitest\\augustus");
3595     RemoveDirectory("msitest");
3596     DeleteFile("maximus");
3597     DeleteFile("test1.cab");
3598     DeleteFile(msifile);
3599 }
3600
3601 static void test_duplicatefiles(void)
3602 {
3603     UINT r;
3604
3605     CreateDirectoryA("msitest", NULL);
3606     create_file("msitest\\maximus", 500);
3607     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
3608
3609     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3610
3611     /* fails if the destination folder is not a valid property */
3612
3613     r = MsiInstallProductA(msifile, NULL);
3614     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3615     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3616     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
3617     ok(delete_pf("msitest\\this\\doesnt\\exist\\maximus", TRUE), "File not duplicated\n");
3618     ok(delete_pf("msitest\\this\\doesnt\\exist", FALSE), "File not duplicated\n");
3619     ok(delete_pf("msitest\\this\\doesnt", FALSE), "File not duplicated\n");
3620     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
3621     ok(delete_pf("msitest", FALSE), "File not installed\n");
3622
3623     DeleteFile("msitest\\maximus");
3624     RemoveDirectory("msitest");
3625     DeleteFile(msifile);
3626 }
3627
3628 START_TEST(install)
3629 {
3630     DWORD len;
3631     char temp_path[MAX_PATH], prev_path[MAX_PATH];
3632
3633     init_functionpointers();
3634
3635     GetCurrentDirectoryA(MAX_PATH, prev_path);
3636     GetTempPath(MAX_PATH, temp_path);
3637     SetCurrentDirectoryA(temp_path);
3638
3639     lstrcpyA(CURR_DIR, temp_path);
3640     len = lstrlenA(CURR_DIR);
3641
3642     if(len && (CURR_DIR[len - 1] == '\\'))
3643         CURR_DIR[len - 1] = 0;
3644
3645     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
3646
3647     test_MsiInstallProduct();
3648     test_MsiSetComponentState();
3649     test_packagecoltypes();
3650     test_continuouscabs();
3651     test_caborder();
3652     test_mixedmedia();
3653     test_samesequence();
3654     test_uiLevelFlags();
3655     test_readonlyfile();
3656     test_setdirproperty();
3657     test_cabisextracted();
3658     test_concurrentinstall();
3659     test_setpropertyfolder();
3660     test_publish();
3661     test_publishsourcelist();
3662     test_transformprop();
3663     test_currentworkingdir();
3664     test_admin();
3665     test_adminprops();
3666     test_removefiles();
3667     test_movefiles();
3668     test_missingcab();
3669     test_duplicatefiles();
3670
3671     SetCurrentDirectoryA(prev_path);
3672 }