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