mshtml: Fixed handling channels without container and necko channel.
[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\t1477005400\t-2141257985\t284379198\t21485139";
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(const CHAR *name, DWORD size)
1104 {
1105     HANDLE file;
1106     DWORD written, left;
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, name, strlen(name), &written, NULL);
1111     WriteFile(file, "\n", strlen("\n"), &written, NULL);
1112
1113     left = size - lstrlen(name) - 1;
1114
1115     SetFilePointer(file, left, NULL, FILE_CURRENT);
1116     SetEndOfFile(file);
1117     
1118     CloseHandle(file);
1119 }
1120
1121 static void create_test_files(void)
1122 {
1123     CreateDirectoryA("msitest", NULL);
1124     create_file("msitest\\one.txt", 100);
1125     CreateDirectoryA("msitest\\first", NULL);
1126     create_file("msitest\\first\\two.txt", 100);
1127     CreateDirectoryA("msitest\\second", NULL);
1128     create_file("msitest\\second\\three.txt", 100);
1129
1130     create_file("four.txt", 100);
1131     create_file("five.txt", 100);
1132     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1133
1134     create_file("msitest\\filename", 100);
1135     create_file("msitest\\service.exe", 100);
1136
1137     DeleteFileA("four.txt");
1138     DeleteFileA("five.txt");
1139 }
1140
1141 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1142 {
1143     CHAR path[MAX_PATH];
1144
1145     lstrcpyA(path, PROG_FILES_DIR);
1146     lstrcatA(path, "\\");
1147     lstrcatA(path, rel_path);
1148
1149     if (is_file)
1150         return DeleteFileA(path);
1151     else
1152         return RemoveDirectoryA(path);
1153 }
1154
1155 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1156 {
1157     CHAR path[MAX_PATH];
1158
1159     lstrcpyA(path, COMMON_FILES_DIR);
1160     lstrcatA(path, "\\");
1161     lstrcatA(path, rel_path);
1162
1163     if (is_file)
1164         return DeleteFileA(path);
1165     else
1166         return RemoveDirectoryA(path);
1167 }
1168
1169 static void delete_test_files(void)
1170 {
1171     DeleteFileA("msitest.msi");
1172     DeleteFileA("msitest.cab");
1173     DeleteFileA("msitest\\second\\three.txt");
1174     DeleteFileA("msitest\\first\\two.txt");
1175     DeleteFileA("msitest\\one.txt");
1176     DeleteFileA("msitest\\service.exe");
1177     DeleteFileA("msitest\\filename");
1178     RemoveDirectoryA("msitest\\second");
1179     RemoveDirectoryA("msitest\\first");
1180     RemoveDirectoryA("msitest");
1181 }
1182
1183 static void write_file(const CHAR *filename, const char *data, int data_size)
1184 {
1185     DWORD size;
1186
1187     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1188                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1189
1190     WriteFile(hf, data, data_size, &size, NULL);
1191     CloseHandle(hf);
1192 }
1193
1194 static void write_msi_summary_info(MSIHANDLE db)
1195 {
1196     MSIHANDLE summary;
1197     UINT r;
1198
1199     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1201
1202     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1204
1205     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1206                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1207     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1208
1209     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1211
1212     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1214
1215     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1217
1218     /* write the summary changes back to the stream */
1219     r = MsiSummaryInfoPersist(summary);
1220     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1221
1222     MsiCloseHandle(summary);
1223 }
1224
1225 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1226 {
1227     MSIHANDLE db;
1228     UINT r;
1229     int j;
1230
1231     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1232     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1233
1234     /* import the tables into the database */
1235     for (j = 0; j < num_tables; j++)
1236     {
1237         const msi_table *table = &tables[j];
1238
1239         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1240
1241         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1242         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1243
1244         DeleteFileA(table->filename);
1245     }
1246
1247     write_msi_summary_info(db);
1248
1249     r = MsiDatabaseCommit(db);
1250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1251
1252     MsiCloseHandle(db);
1253 }
1254
1255 static void check_service_is_installed(void)
1256 {
1257     SC_HANDLE scm, service;
1258     BOOL res;
1259
1260     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1261     ok(scm != NULL, "Failed to open the SC Manager\n");
1262
1263     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1264     ok(service != NULL, "Failed to open TestService\n");
1265
1266     res = DeleteService(service);
1267     ok(res, "Failed to delete TestService\n");
1268 }
1269
1270 static void test_MsiInstallProduct(void)
1271 {
1272     UINT r;
1273     CHAR path[MAX_PATH];
1274     LONG res;
1275     HKEY hkey;
1276     DWORD num, size, type;
1277
1278     create_test_files();
1279     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1280
1281     r = MsiInstallProductA(msifile, NULL);
1282     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1283
1284     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1285     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1286     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1287     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1288     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1289     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1290     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1291     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1292     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1293     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1294     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1295     ok(delete_pf("msitest", FALSE), "File not installed\n");
1296
1297     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1299
1300     size = MAX_PATH;
1301     type = REG_SZ;
1302     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1304     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1305
1306     size = MAX_PATH;
1307     type = REG_SZ;
1308     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1309     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1310
1311     size = sizeof(num);
1312     type = REG_DWORD;
1313     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1315     ok(num == 314, "Expected 314, got %d\n", num);
1316
1317     size = MAX_PATH;
1318     type = REG_SZ;
1319     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1320     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1321     ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1322
1323     check_service_is_installed();
1324
1325     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1326
1327     delete_test_files();
1328 }
1329
1330 static void test_MsiSetComponentState(void)
1331 {
1332     INSTALLSTATE installed, action;
1333     MSIHANDLE package;
1334     char path[MAX_PATH];
1335     UINT r;
1336
1337     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1338
1339     CoInitialize(NULL);
1340
1341     lstrcpy(path, CURR_DIR);
1342     lstrcat(path, "\\");
1343     lstrcat(path, msifile);
1344
1345     r = MsiOpenPackage(path, &package);
1346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1347
1348     r = MsiDoAction(package, "CostInitialize");
1349     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1350
1351     r = MsiDoAction(package, "FileCost");
1352     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1353
1354     r = MsiDoAction(package, "CostFinalize");
1355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1356
1357     r = MsiGetComponentState(package, "dangler", &installed, &action);
1358     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1359     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1360     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1361
1362     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1364
1365     MsiCloseHandle(package);
1366     CoUninitialize();
1367
1368     DeleteFileA(msifile);
1369 }
1370
1371 static void test_packagecoltypes(void)
1372 {
1373     MSIHANDLE hdb, view, rec;
1374     char path[MAX_PATH];
1375     LPCSTR query;
1376     UINT r, count;
1377
1378     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1379
1380     CoInitialize(NULL);
1381
1382     lstrcpy(path, CURR_DIR);
1383     lstrcat(path, "\\");
1384     lstrcat(path, msifile);
1385
1386     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1387     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1388
1389     query = "SELECT * FROM `Media`";
1390     r = MsiDatabaseOpenView( hdb, query, &view );
1391     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1392
1393     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1394     count = MsiRecordGetFieldCount( rec );
1395     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1396     ok(count == 6, "Expected 6, got %d\n", count);
1397     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1398     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1399     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1400     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1401     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1402     ok(check_record(rec, 6, "Source"), "wrong column label\n");
1403     MsiCloseHandle(rec);
1404
1405     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1406     count = MsiRecordGetFieldCount( rec );
1407     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1408     ok(count == 6, "Expected 6, got %d\n", count);
1409     ok(check_record(rec, 1, "i2"), "wrong column label\n");
1410     ok(check_record(rec, 2, "i4"), "wrong column label\n");
1411     ok(check_record(rec, 3, "L64"), "wrong column label\n");
1412     ok(check_record(rec, 4, "S255"), "wrong column label\n");
1413     ok(check_record(rec, 5, "S32"), "wrong column label\n");
1414     ok(check_record(rec, 6, "S72"), "wrong column label\n");
1415
1416     MsiCloseHandle(rec);
1417     MsiCloseHandle(view);
1418     MsiCloseHandle(hdb);
1419     DeleteFile(msifile);
1420 }
1421
1422 static void create_cc_test_files(void)
1423 {
1424     CCAB cabParams;
1425     HFCI hfci;
1426     ERF erf;
1427     static CHAR cab_context[] = "test%d.cab";
1428     BOOL res;
1429
1430     create_file("maximus", 500);
1431     create_file("augustus", 50000);
1432     create_file("caesar", 500);
1433
1434     set_cab_parameters(&cabParams, "test1.cab", 200);
1435
1436     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1437                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1438                       get_temp_file, &cabParams, cab_context);
1439     ok(hfci != NULL, "Failed to create an FCI context\n");
1440
1441     res = add_file(hfci, "maximus", tcompTYPE_MSZIP);
1442     ok(res, "Failed to add file maximus\n");
1443
1444     res = add_file(hfci, "augustus", tcompTYPE_MSZIP);
1445     ok(res, "Failed to add file augustus\n");
1446
1447     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1448     ok(res, "Failed to flush the cabinet\n");
1449
1450     res = FCIDestroy(hfci);
1451     ok(res, "Failed to destroy the cabinet\n");
1452
1453     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1454
1455     DeleteFile("maximus");
1456     DeleteFile("augustus");
1457     DeleteFile("caesar");
1458 }
1459
1460 static void delete_cab_files(void)
1461 {
1462     SHFILEOPSTRUCT shfl;
1463     CHAR path[MAX_PATH+10];
1464
1465     lstrcpyA(path, CURR_DIR);
1466     lstrcatA(path, "\\*.cab");
1467     path[strlen(path) + 1] = '\0';
1468
1469     shfl.hwnd = NULL;
1470     shfl.wFunc = FO_DELETE;
1471     shfl.pFrom = path;
1472     shfl.pTo = NULL;
1473     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1474
1475     SHFileOperation(&shfl);
1476 }
1477
1478 static void test_continuouscabs(void)
1479 {
1480     UINT r;
1481
1482     create_cc_test_files();
1483     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1484
1485     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1486
1487     r = MsiInstallProductA(msifile, NULL);
1488     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1489     todo_wine
1490     {
1491         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1492         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1493         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1494     }
1495     ok(delete_pf("msitest", FALSE), "File not installed\n");
1496
1497     delete_cab_files();
1498     DeleteFile(msifile);
1499 }
1500
1501 static void test_caborder(void)
1502 {
1503     UINT r;
1504
1505     create_file("imperator", 100);
1506     create_file("maximus", 500);
1507     create_file("augustus", 50000);
1508     create_file("caesar", 500);
1509
1510     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1511
1512     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1513
1514     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1515     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1516     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1517
1518     r = MsiInstallProductA(msifile, NULL);
1519     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1520     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1521     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1522     todo_wine
1523     {
1524         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1525         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1526     }
1527
1528     delete_cab_files();
1529
1530     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1531     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1532     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1533
1534     r = MsiInstallProductA(msifile, NULL);
1535     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1536     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1537     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1538     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1539     todo_wine
1540     {
1541         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1542     }
1543
1544     delete_cab_files();
1545     DeleteFile(msifile);
1546
1547     create_cc_test_files();
1548     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1549
1550     r = MsiInstallProductA(msifile, NULL);
1551     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1552     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1553     ok(!delete_pf("msitest", FALSE), "File is installed\n");
1554     todo_wine
1555     {
1556         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1557         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1558     }
1559
1560     delete_cab_files();
1561     DeleteFile(msifile);
1562
1563     create_cc_test_files();
1564     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1565
1566     r = MsiInstallProductA(msifile, NULL);
1567     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1568     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1569     todo_wine
1570     {
1571         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1572         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1573         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1574     }
1575
1576     delete_cab_files();
1577     DeleteFile("imperator");
1578     DeleteFile("maximus");
1579     DeleteFile("augustus");
1580     DeleteFile("caesar");
1581     DeleteFile(msifile);
1582 }
1583
1584 static void test_mixedmedia(void)
1585 {
1586     UINT r;
1587
1588     CreateDirectoryA("msitest", NULL);
1589     create_file("msitest\\maximus", 500);
1590     create_file("msitest\\augustus", 500);
1591     create_file("caesar", 500);
1592
1593     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1594
1595     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1596
1597     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1598
1599     r = MsiInstallProductA(msifile, NULL);
1600     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1601     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1602     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1603     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1604     ok(delete_pf("msitest", FALSE), "File not installed\n");
1605
1606     /* Delete the files in the temp (current) folder */
1607     DeleteFile("msitest\\maximus");
1608     DeleteFile("msitest\\augustus");
1609     RemoveDirectory("msitest");
1610     DeleteFile("caesar");
1611     DeleteFile("test1.cab");
1612     DeleteFile(msifile);
1613 }
1614
1615 static void test_samesequence(void)
1616 {
1617     UINT r;
1618
1619     create_cc_test_files();
1620     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1621
1622     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1623
1624     r = MsiInstallProductA(msifile, NULL);
1625     todo_wine
1626     {
1627         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1628         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1629         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1630     }
1631     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1632     ok(delete_pf("msitest", FALSE), "File not installed\n");
1633
1634     delete_cab_files();
1635     DeleteFile(msifile);
1636 }
1637
1638 static void test_uiLevelFlags(void)
1639 {
1640     UINT r;
1641
1642     create_cc_test_files();
1643     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1644
1645     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1646
1647     r = MsiInstallProductA(msifile, NULL);
1648     ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1649     todo_wine
1650     {
1651         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1652         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1653     }
1654     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1655     ok(delete_pf("msitest", FALSE), "File not installed\n");
1656
1657     delete_cab_files();
1658     DeleteFile(msifile);
1659 }
1660
1661 static BOOL file_matches(LPSTR path)
1662 {
1663     CHAR buf[MAX_PATH];
1664     HANDLE file;
1665     DWORD size;
1666
1667     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1668                       NULL, OPEN_EXISTING, 0, NULL);
1669
1670     ZeroMemory(buf, MAX_PATH);
1671     ReadFile(file, buf, 15, &size, NULL);
1672     CloseHandle(file);
1673
1674     return !lstrcmp(buf, "msitest\\maximus");
1675 }
1676
1677 static void test_readonlyfile(void)
1678 {
1679     UINT r;
1680     DWORD size;
1681     HANDLE file;
1682     CHAR path[MAX_PATH];
1683
1684     CreateDirectoryA("msitest", NULL);
1685     create_file("msitest\\maximus", 500);
1686     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1687
1688     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1689
1690     lstrcpy(path, PROG_FILES_DIR);
1691     lstrcat(path, "\\msitest");
1692     CreateDirectory(path, NULL);
1693
1694     lstrcat(path, "\\maximus");
1695     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1696                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1697
1698     WriteFile(file, "readonlyfile", 20, &size, NULL);
1699     CloseHandle(file);
1700
1701     r = MsiInstallProductA(msifile, NULL);
1702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1703     ok(file_matches(path), "Expected file to be overwritten\n");
1704     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1705     ok(delete_pf("msitest", FALSE), "File not installed\n");
1706
1707     /* Delete the files in the temp (current) folder */
1708     DeleteFile("msitest\\maximus");
1709     RemoveDirectory("msitest");
1710     DeleteFile(msifile);
1711 }
1712
1713 static void test_setdirproperty(void)
1714 {
1715     UINT r;
1716
1717     CreateDirectoryA("msitest", NULL);
1718     create_file("msitest\\maximus", 500);
1719     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1720
1721     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1722
1723     r = MsiInstallProductA(msifile, NULL);
1724     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1725     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1726     ok(delete_cf("msitest", FALSE), "File not installed\n");
1727
1728     /* Delete the files in the temp (current) folder */
1729     DeleteFile(msifile);
1730     DeleteFile("msitest\\maximus");
1731     RemoveDirectory("msitest");
1732 }
1733
1734 static void test_cabisextracted(void)
1735 {
1736     UINT r;
1737
1738     CreateDirectoryA("msitest", NULL);
1739     create_file("msitest\\gaius", 500);
1740     create_file("maximus", 500);
1741     create_file("augustus", 500);
1742     create_file("caesar", 500);
1743
1744     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1745     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1746     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1747
1748     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
1749
1750     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1751
1752     r = MsiInstallProductA(msifile, NULL);
1753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1754     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1755     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1756     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1757     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
1758     ok(delete_pf("msitest", FALSE), "File not installed\n");
1759
1760     /* Delete the files in the temp (current) folder */
1761     delete_cab_files();
1762     DeleteFile(msifile);
1763     DeleteFile("maximus");
1764     DeleteFile("augustus");
1765     DeleteFile("caesar");
1766     DeleteFile("msitest\\gaius");
1767     RemoveDirectory("msitest");
1768 }
1769
1770 static void test_concurrentinstall(void)
1771 {
1772     UINT r;
1773     CHAR path[MAX_PATH];
1774
1775     CreateDirectoryA("msitest", NULL);
1776     CreateDirectoryA("msitest\\msitest", NULL);
1777     create_file("msitest\\maximus", 500);
1778     create_file("msitest\\msitest\\augustus", 500);
1779
1780     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
1781
1782     lstrcpyA(path, CURR_DIR);
1783     lstrcatA(path, "\\msitest\\concurrent.msi");
1784     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
1785
1786     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1787
1788     r = MsiInstallProductA(msifile, NULL);
1789     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1790     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1791     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1792     ok(delete_pf("msitest", FALSE), "File not installed\n");
1793
1794     /* Delete the files in the temp (current) folder */
1795     DeleteFile(msifile);
1796     DeleteFile(path);
1797     DeleteFile("msitest\\msitest\\augustus");
1798     DeleteFile("msitest\\maximus");
1799     RemoveDirectory("msitest\\msitest");
1800     RemoveDirectory("msitest");
1801 }
1802
1803 static void test_setpropertyfolder(void)
1804 {
1805     UINT r;
1806
1807     CreateDirectoryA("msitest", NULL);
1808     create_file("msitest\\maximus", 500);
1809
1810     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
1811
1812     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1813
1814     r = MsiInstallProductA(msifile, NULL);
1815     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1816     ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
1817     ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
1818     ok(delete_pf("msitest", FALSE), "File not installed\n");
1819
1820     /* Delete the files in the temp (current) folder */
1821     DeleteFile(msifile);
1822     DeleteFile("msitest\\maximus");
1823     RemoveDirectory("msitest");
1824 }
1825
1826 static BOOL file_exists(LPCSTR file)
1827 {
1828     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
1829 }
1830
1831 static BOOL pf_exists(LPCSTR file)
1832 {
1833     CHAR path[MAX_PATH];
1834
1835     lstrcpyA(path, PROG_FILES_DIR);
1836     lstrcatA(path, "\\");
1837     lstrcatA(path, file);
1838
1839     return file_exists(path);
1840 }
1841
1842 static void delete_pfmsitest_files(void)
1843 {
1844     SHFILEOPSTRUCT shfl;
1845     CHAR path[MAX_PATH+11];
1846
1847     lstrcpyA(path, PROG_FILES_DIR);
1848     lstrcatA(path, "\\msitest\\*");
1849     path[strlen(path) + 1] = '\0';
1850
1851     shfl.hwnd = NULL;
1852     shfl.wFunc = FO_DELETE;
1853     shfl.pFrom = path;
1854     shfl.pTo = NULL;
1855     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1856
1857     SHFileOperation(&shfl);
1858
1859     lstrcpyA(path, PROG_FILES_DIR);
1860     lstrcatA(path, "\\msitest");
1861     RemoveDirectoryA(path);
1862 }
1863
1864 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
1865 {
1866     char val[MAX_PATH];
1867     DWORD size, type;
1868     LONG res;
1869
1870     size = MAX_PATH;
1871     val[0] = '\0';
1872     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
1873
1874     if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
1875     {
1876         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
1877         return;
1878     }
1879
1880     if (!expected)
1881         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
1882     else
1883     {
1884         if (bcase)
1885             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
1886         else
1887             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
1888     }
1889 }
1890
1891 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
1892 {
1893     DWORD val, size, type;
1894     LONG res;
1895
1896     size = sizeof(DWORD);
1897     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
1898
1899     if (res != ERROR_SUCCESS || type != REG_DWORD)
1900     {
1901         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
1902         return;
1903     }
1904
1905     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
1906 }
1907
1908 #define CHECK_REG_STR(prodkey, name, expected) \
1909     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
1910
1911 #define CHECK_REG_ISTR(prodkey, name, expected) \
1912     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
1913
1914 #define CHECK_REG_DWORD(prodkey, name, expected) \
1915     check_reg_dword(prodkey, name, expected, __LINE__);
1916
1917 static void get_date_str(LPSTR date)
1918 {
1919     SYSTEMTIME systime;
1920
1921     static const char date_fmt[] = "%d%d%d";
1922     GetLocalTime(&systime);
1923     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
1924 }
1925
1926 static void test_publish(void)
1927 {
1928     UINT r;
1929     LONG res;
1930     HKEY uninstall, prodkey;
1931     INSTALLSTATE state;
1932     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
1933     char date[MAX_PATH];
1934     char temp[MAX_PATH];
1935
1936     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
1937
1938     get_date_str(date);
1939     GetTempPath(MAX_PATH, temp);
1940
1941     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
1942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1943
1944     CreateDirectoryA("msitest", NULL);
1945     create_file("msitest\\maximus", 500);
1946
1947     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
1948
1949     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1950
1951     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1952     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1953
1954     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1955     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1956
1957     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1958     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1959
1960     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1961                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1962     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1963     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1964
1965     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
1966     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1967
1968     /* nothing published */
1969     r = MsiInstallProductA(msifile, NULL);
1970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1971     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1972     ok(pf_exists("msitest"), "File not installed\n");
1973
1974     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1975     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1976
1977     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1978     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1979
1980     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1981     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1982
1983     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1984                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1985     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1986     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1987
1988     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
1989     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1990
1991     /* install again */
1992     r = MsiInstallProductA(msifile, NULL);
1993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1994     ok(pf_exists("msitest\\maximus"), "File not installed\n");
1995     ok(pf_exists("msitest"), "File not installed\n");
1996
1997     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1998     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1999
2000     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2001     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2002
2003     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2004     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2005
2006     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2007                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2008     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2009     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2010
2011     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2012     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2013
2014     /* try to uninstall */
2015     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2016     todo_wine
2017     {
2018         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2019     }
2020     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2021     ok(pf_exists("msitest"), "File deleted\n");
2022
2023     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2024     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2025
2026     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2027     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2028
2029     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2030     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2031
2032     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2033                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2034     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2035     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2036
2037     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2038     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2039
2040     /* PublishProduct */
2041     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2043     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2044     ok(pf_exists("msitest"), "File not installed\n");
2045
2046     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2047     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2048
2049     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2050     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2051
2052     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2053                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2054     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2055     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2056
2057     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2058     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2059
2060     /* try to uninstall after PublishProduct */
2061     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2062     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2063     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2064     ok(pf_exists("msitest"), "File deleted\n");
2065
2066     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2067     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2068
2069     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2070     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2071
2072     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2073     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2074
2075     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2076                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2077     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2078     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2079
2080     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2081     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2082
2083     /* RegisterProduct */
2084     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2085     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2086     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2087     ok(pf_exists("msitest"), "File not installed\n");
2088
2089     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2090     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2091
2092     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2093     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2094
2095     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2096                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2097     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2098     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2099
2100     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2101     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2102
2103     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2104     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2105     CHECK_REG_STR(prodkey, "InstallDate", date);
2106     CHECK_REG_STR(prodkey, "InstallSource", temp);
2107     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2108     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2109     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2110     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2111     CHECK_REG_STR(prodkey, "Comments", NULL);
2112     CHECK_REG_STR(prodkey, "Contact", NULL);
2113     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2114     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2115     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2116     CHECK_REG_STR(prodkey, "Readme", NULL);
2117     CHECK_REG_STR(prodkey, "Size", NULL);
2118     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2119     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2120     CHECK_REG_DWORD(prodkey, "Language", 1033);
2121     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2122     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2123     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2124     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2125     todo_wine
2126     {
2127         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2128     }
2129
2130     RegCloseKey(prodkey);
2131
2132     /* complete uninstall */
2133     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2134     todo_wine
2135     {
2136         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2137     }
2138     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2139     ok(pf_exists("msitest"), "File deleted\n");
2140
2141     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2142     todo_wine
2143     {
2144         ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2145     }
2146
2147     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2148     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2149
2150     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2151     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2152
2153     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2154                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2155     todo_wine
2156     {
2157         ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2158     }
2159     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2160
2161     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2163
2164     todo_wine
2165     {
2166         CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2167         CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2168         CHECK_REG_STR(prodkey, "InstallDate", date);
2169         CHECK_REG_STR(prodkey, "InstallSource", temp);
2170         CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2171         CHECK_REG_STR(prodkey, "Publisher", "Wine");
2172         CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2173         CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2174         CHECK_REG_STR(prodkey, "Comments", NULL);
2175         CHECK_REG_STR(prodkey, "Contact", NULL);
2176         CHECK_REG_STR(prodkey, "HelpLink", NULL);
2177         CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2178         CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2179         CHECK_REG_STR(prodkey, "Readme", NULL);
2180         CHECK_REG_STR(prodkey, "Size", NULL);
2181         CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2182         CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2183         CHECK_REG_DWORD(prodkey, "Language", 1033);
2184         CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2185         CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2186         CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2187         CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2188         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2189     }
2190
2191     RegCloseKey(prodkey);
2192
2193     /* PublishProduct and RegisterProduct */
2194     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
2195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2196     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2197     ok(pf_exists("msitest"), "File not installed\n");
2198
2199     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2200     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2201
2202     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2203     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2204
2205     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2206     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2207
2208     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2209                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2210     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2211     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2212
2213     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2214     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2215
2216     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2217     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2218     CHECK_REG_STR(prodkey, "InstallDate", date);
2219     CHECK_REG_STR(prodkey, "InstallSource", temp);
2220     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2221     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2222     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2223     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2224     CHECK_REG_STR(prodkey, "Comments", NULL);
2225     CHECK_REG_STR(prodkey, "Contact", NULL);
2226     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2227     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2228     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2229     CHECK_REG_STR(prodkey, "Readme", NULL);
2230     CHECK_REG_STR(prodkey, "Size", NULL);
2231     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2232     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2233     CHECK_REG_DWORD(prodkey, "Language", 1033);
2234     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2235     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2236     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2237     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2238     todo_wine
2239     {
2240         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2241     }
2242
2243     RegCloseKey(prodkey);
2244
2245     /* try it again */
2246     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
2247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2248     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2249     ok(pf_exists("msitest"), "File not installed\n");
2250
2251     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2252     todo_wine
2253     {
2254         ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2255     }
2256
2257     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2258     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2259
2260     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2261     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2262
2263     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2264                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2265     todo_wine
2266     {
2267         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2268     }
2269     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2270
2271     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2272     todo_wine
2273     {
2274         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2275     }
2276
2277     /* uninstall has a problem with this */
2278     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2279     todo_wine
2280     {
2281         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2282     }
2283     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2284     ok(pf_exists("msitest"), "File deleted\n");
2285
2286     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2287     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2288
2289     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2290     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2291
2292     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2293                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2294     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2295     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2296
2297     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2298     todo_wine
2299     {
2300         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2301     }
2302
2303     /* PublishProduct and RegisterProduct and ProcessComponents */
2304     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
2305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2306     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2307     ok(pf_exists("msitest"), "File not installed\n");
2308
2309     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2310     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2311
2312     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2313     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2314
2315     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2316     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2317
2318     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2319                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2321     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2322
2323     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2325
2326     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2327     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2328     CHECK_REG_STR(prodkey, "InstallDate", date);
2329     CHECK_REG_STR(prodkey, "InstallSource", temp);
2330     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2331     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2332     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2333     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2334     CHECK_REG_STR(prodkey, "Comments", NULL);
2335     CHECK_REG_STR(prodkey, "Contact", NULL);
2336     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2337     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2338     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2339     CHECK_REG_STR(prodkey, "Readme", NULL);
2340     CHECK_REG_STR(prodkey, "Size", NULL);
2341     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2342     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2343     CHECK_REG_DWORD(prodkey, "Language", 1033);
2344     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2345     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2346     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2347     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2348     todo_wine
2349     {
2350         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2351     }
2352
2353     RegCloseKey(prodkey);
2354
2355     /* complete uninstall */
2356     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2358     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2359     ok(pf_exists("msitest"), "File deleted\n");
2360
2361     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2362     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2363
2364     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2365     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2366
2367     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2368     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2369
2370     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2371                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2372     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2373     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2374
2375     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2376     todo_wine
2377     {
2378         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2379     }
2380
2381     /* PublishProduct, RegisterProduct, ProcessComponents, PublishFeatures */
2382     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1 PUBLISH_FEATURES=1");
2383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2384     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2385     ok(pf_exists("msitest"), "File not installed\n");
2386
2387     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2388     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2389
2390     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2391     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2392
2393     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2394     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2395
2396     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2397                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2398     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2399     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2400
2401     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2403
2404     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2405     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2406     CHECK_REG_STR(prodkey, "InstallDate", date);
2407     CHECK_REG_STR(prodkey, "InstallSource", temp);
2408     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2409     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2410     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2411     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2412     CHECK_REG_STR(prodkey, "Comments", NULL);
2413     CHECK_REG_STR(prodkey, "Contact", NULL);
2414     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2415     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2416     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2417     CHECK_REG_STR(prodkey, "Readme", NULL);
2418     CHECK_REG_STR(prodkey, "Size", NULL);
2419     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2420     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2421     CHECK_REG_DWORD(prodkey, "Language", 1033);
2422     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2423     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2424     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2425     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2426     todo_wine
2427     {
2428         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2429     }
2430
2431     RegCloseKey(prodkey);
2432
2433     /* complete uninstall */
2434     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2435     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2436     todo_wine
2437     {
2438         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2439         ok(!pf_exists("msitest"), "File deleted\n");
2440     }
2441
2442     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2443     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2444
2445     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");\
2446     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2447
2448     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2449     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2450
2451     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2452                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2453     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2454     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2455
2456     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2457     todo_wine
2458     {
2459         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2460     }
2461
2462     /* complete install */
2463     r = MsiInstallProductA(msifile, "FULL=1");
2464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2465     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2466     ok(pf_exists("msitest"), "File not installed\n");
2467
2468     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2469     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2470
2471     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2472     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2473
2474     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2475     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2476
2477     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2478                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2480     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2481
2482     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2484
2485     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2486     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2487     CHECK_REG_STR(prodkey, "InstallDate", date);
2488     CHECK_REG_STR(prodkey, "InstallSource", temp);
2489     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2490     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2491     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2492     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2493     CHECK_REG_STR(prodkey, "Comments", NULL);
2494     CHECK_REG_STR(prodkey, "Contact", NULL);
2495     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2496     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2497     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2498     CHECK_REG_STR(prodkey, "Readme", NULL);
2499     CHECK_REG_STR(prodkey, "Size", NULL);
2500     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2501     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2502     CHECK_REG_DWORD(prodkey, "Language", 1033);
2503     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2504     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2505     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2506     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2507     todo_wine
2508     {
2509         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2510     }
2511
2512     RegCloseKey(prodkey);
2513
2514     /* no UnpublishFeatures */
2515     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2517     todo_wine
2518     {
2519         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2520         ok(!pf_exists("msitest"), "File deleted\n");
2521     }
2522
2523     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2524     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2525
2526     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2527     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2528
2529     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2530     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2531
2532     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2533                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2534     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2535     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2536
2537     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2538     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2539
2540     /* complete install */
2541     r = MsiInstallProductA(msifile, "FULL=1");
2542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2543     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2544     ok(pf_exists("msitest"), "File not installed\n");
2545
2546     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2547     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2548
2549     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2550     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2551
2552     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2553     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2554
2555     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2556                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2557     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2558     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2559
2560     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2562
2563     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2564     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2565     CHECK_REG_STR(prodkey, "InstallDate", date);
2566     CHECK_REG_STR(prodkey, "InstallSource", temp);
2567     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2568     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2569     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2570     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2571     CHECK_REG_STR(prodkey, "Comments", NULL);
2572     CHECK_REG_STR(prodkey, "Contact", NULL);
2573     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2574     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2575     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2576     CHECK_REG_STR(prodkey, "Readme", NULL);
2577     CHECK_REG_STR(prodkey, "Size", NULL);
2578     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2579     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2580     CHECK_REG_DWORD(prodkey, "Language", 1033);
2581     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2582     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2583     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2584     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2585     todo_wine
2586     {
2587         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2588     }
2589
2590     RegCloseKey(prodkey);
2591
2592     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
2593     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
2594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2595     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2596     ok(pf_exists("msitest"), "File deleted\n");
2597
2598     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2599     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2600
2601     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2602     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2603
2604     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2605     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2606
2607     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2608                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2609     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2610     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2611
2612     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2614
2615     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2616     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2617     CHECK_REG_STR(prodkey, "InstallDate", date);
2618     CHECK_REG_STR(prodkey, "InstallSource", temp);
2619     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2620     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2621     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2622     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2623     CHECK_REG_STR(prodkey, "Comments", NULL);
2624     CHECK_REG_STR(prodkey, "Contact", NULL);
2625     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2626     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2627     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2628     CHECK_REG_STR(prodkey, "Readme", NULL);
2629     CHECK_REG_STR(prodkey, "Size", NULL);
2630     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2631     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2632     CHECK_REG_DWORD(prodkey, "Language", 1033);
2633     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2634     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2635     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2636     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2637     todo_wine
2638     {
2639         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2640     }
2641
2642     RegCloseKey(prodkey);
2643
2644     /* complete install */
2645     r = MsiInstallProductA(msifile, "FULL=1");
2646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2647     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2648     ok(pf_exists("msitest"), "File not installed\n");
2649
2650     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2651     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2652
2653     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2654     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2655
2656     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2657     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2658
2659     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2660                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2662     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2663
2664     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2666
2667     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2668     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2669     CHECK_REG_STR(prodkey, "InstallDate", date);
2670     CHECK_REG_STR(prodkey, "InstallSource", temp);
2671     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2672     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2673     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2674     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2675     CHECK_REG_STR(prodkey, "Comments", NULL);
2676     CHECK_REG_STR(prodkey, "Contact", NULL);
2677     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2678     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2679     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2680     CHECK_REG_STR(prodkey, "Readme", NULL);
2681     CHECK_REG_STR(prodkey, "Size", NULL);
2682     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2683     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2684     CHECK_REG_DWORD(prodkey, "Language", 1033);
2685     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2686     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2687     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2688     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2689     todo_wine
2690     {
2691         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2692     }
2693
2694     RegCloseKey(prodkey);
2695
2696     /* UnpublishFeatures, both features removed */
2697     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
2698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2699     todo_wine
2700     {
2701         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2702         ok(!pf_exists("msitest"), "File not deleted\n");
2703     }
2704
2705     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2706     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2707
2708     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2709     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2710
2711     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2712     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2713
2714     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2715                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2716     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2717     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2718
2719     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2720     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2721
2722     /* complete install */
2723     r = MsiInstallProductA(msifile, "FULL=1");
2724     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2725     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2726     ok(pf_exists("msitest"), "File not installed\n");
2727
2728     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2729     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2730
2731     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2732     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2733
2734     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2735     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2736
2737     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2738                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2740     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2741
2742     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2744
2745     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2746     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2747     CHECK_REG_STR(prodkey, "InstallDate", date);
2748     CHECK_REG_STR(prodkey, "InstallSource", temp);
2749     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2750     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2751     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2752     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2753     CHECK_REG_STR(prodkey, "Comments", NULL);
2754     CHECK_REG_STR(prodkey, "Contact", NULL);
2755     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2756     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2757     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2758     CHECK_REG_STR(prodkey, "Readme", NULL);
2759     CHECK_REG_STR(prodkey, "Size", NULL);
2760     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2761     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2762     CHECK_REG_DWORD(prodkey, "Language", 1033);
2763     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2764     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2765     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2766     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2767     todo_wine
2768     {
2769         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2770     }
2771
2772     RegCloseKey(prodkey);
2773
2774     /* complete uninstall */
2775     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2777     todo_wine
2778     {
2779         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2780         ok(!pf_exists("msitest"), "File not deleted\n");
2781     }
2782
2783     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2784     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2785
2786     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2787     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2788
2789     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2790     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2791
2792     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2793                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2794     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2795     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2796
2797     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2798     todo_wine
2799     {
2800         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2801     }
2802
2803     /* make sure 'Program Files\msitest' is removed */
2804     delete_pfmsitest_files();
2805
2806     RegCloseKey(uninstall);
2807     DeleteFile(msifile);
2808     DeleteFile("msitest\\maximus");
2809     RemoveDirectory("msitest");
2810 }
2811
2812 static void test_publishsourcelist(void)
2813 {
2814     UINT r;
2815     DWORD size;
2816     CHAR value[MAX_PATH];
2817     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2818
2819     CreateDirectoryA("msitest", NULL);
2820     create_file("msitest\\maximus", 500);
2821
2822     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2823
2824     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2825
2826     r = MsiInstallProductA(msifile, NULL);
2827     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2828     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2829     ok(pf_exists("msitest"), "File not installed\n");
2830
2831     /* nothing published */
2832     size = 0xdeadbeef;
2833     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2834                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2835     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2836     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2837
2838     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2839     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2840     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2841     ok(pf_exists("msitest"), "File not installed\n");
2842
2843     /* after RegisterProduct */
2844     size = 0xdeadbeef;
2845     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2846                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2847     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2848     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2849
2850     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
2851     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2852     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2853     ok(pf_exists("msitest"), "File not installed\n");
2854
2855     /* after ProcessComponents */
2856     size = 0xdeadbeef;
2857     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2858                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2859     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2860     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2861
2862     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2863     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2864     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2865     ok(pf_exists("msitest"), "File not installed\n");
2866
2867     /* after PublishFeatures */
2868     size = 0xdeadbeef;
2869     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2870                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2871     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2872     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2873
2874     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2875     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2876     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2877     ok(pf_exists("msitest"), "File not installed\n");
2878
2879     /* after PublishProduct */
2880     size = MAX_PATH;
2881     lstrcpyA(value, "aaa");
2882     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2883                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
2884     todo_wine
2885     {
2886         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2887         ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
2888         ok(size == 11, "Expected 11, got %d\n", size);
2889     }
2890
2891     /* complete uninstall */
2892     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2893     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2894     todo_wine
2895     {
2896         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2897         ok(!pf_exists("msitest"), "File not deleted\n");
2898     }
2899
2900     /* make sure 'Program Files\msitest' is removed */
2901     delete_pfmsitest_files();
2902
2903     DeleteFile(msifile);
2904     DeleteFile("msitest\\maximus");
2905     RemoveDirectory("msitest");
2906 }
2907
2908 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
2909 {
2910     MSIHANDLE hview = 0;
2911     UINT r;
2912
2913     r = MsiDatabaseOpenView(hdb, query, &hview);
2914     if(r != ERROR_SUCCESS)
2915         return r;
2916
2917     r = MsiViewExecute(hview, hrec);
2918     if(r == ERROR_SUCCESS)
2919         r = MsiViewClose(hview);
2920     MsiCloseHandle(hview);
2921     return r;
2922 }
2923
2924 static void set_transform_summary_info(void)
2925 {
2926     UINT r;
2927     MSIHANDLE suminfo = 0;
2928
2929     /* build summmary info */
2930     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
2931     todo_wine
2932     {
2933         ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
2934     }
2935
2936     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2937     todo_wine
2938     {
2939         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2940     }
2941
2942     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2943                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2944                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2945                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
2946     todo_wine
2947     {
2948         ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
2949     }
2950
2951     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
2952     todo_wine
2953     {
2954         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2955     }
2956
2957     r = MsiSummaryInfoPersist(suminfo);
2958     todo_wine
2959     {
2960         ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
2961     }
2962
2963     r = MsiCloseHandle(suminfo);
2964     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
2965 }
2966
2967 static void generate_transform(void)
2968 {
2969     MSIHANDLE hdb1, hdb2;
2970     LPCSTR query;
2971     UINT r;
2972
2973     /* start with two identical databases */
2974     CopyFile(msifile, msifile2, FALSE);
2975
2976     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
2977     ok(r == ERROR_SUCCESS , "Failed to create database\n");
2978
2979     r = MsiDatabaseCommit(hdb1);
2980     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
2981
2982     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
2983     ok(r == ERROR_SUCCESS , "Failed to create database\n");
2984
2985     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
2986     r = run_query(hdb1, 0, query);
2987     ok(r == ERROR_SUCCESS, "failed to add property\n");
2988
2989     /* database needs to be committed */
2990     MsiDatabaseCommit(hdb1);
2991
2992     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
2993     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
2994
2995 #if 0  /* not implemented in wine yet */
2996     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
2997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2998 #endif
2999
3000     MsiCloseHandle(hdb1);
3001     MsiCloseHandle(hdb2);
3002 }
3003
3004 /* data for generating a transform */
3005
3006 /* tables transform names - encoded as they would be in an msi database file */
3007 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3008 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3009 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3010
3011 /* data in each table */
3012 static const char data1[] = /* _StringData */
3013     "propval";  /* all the strings squashed together */
3014
3015 static const WCHAR data2[] = { /* _StringPool */
3016 /*  len, refs */
3017     0,   0,    /* string 0 ''     */
3018     4,   1,    /* string 1 'prop' */
3019     3,   1,    /* string 2 'val'  */
3020 };
3021
3022 static const WCHAR data3[] = { /* Property */
3023     0x0201, 0x0001, 0x0002,
3024 };
3025
3026 static const struct {
3027     LPCWSTR name;
3028     const void *data;
3029     DWORD size;
3030 } table_transform_data[] =
3031 {
3032     { name1, data1, sizeof data1 - 1 },
3033     { name2, data2, sizeof data2 },
3034     { name3, data3, sizeof data3 },
3035 };
3036
3037 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
3038
3039 static void generate_transform_manual(void)
3040 {
3041     IStorage *stg = NULL;
3042     IStream *stm;
3043     WCHAR name[0x20];
3044     HRESULT r;
3045     DWORD i, count;
3046     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
3047
3048     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
3049
3050     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
3051
3052     r = StgCreateDocfile(name, mode, 0, &stg);
3053     ok(r == S_OK, "failed to create storage\n");
3054     if (!stg)
3055         return;
3056
3057     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
3058     ok(r == S_OK, "failed to set storage type\n");
3059
3060     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
3061     {
3062         r = IStorage_CreateStream(stg, table_transform_data[i].name,
3063                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3064         if (FAILED(r))
3065         {
3066             ok(0, "failed to create stream %08x\n", r);
3067             continue;
3068         }
3069
3070         r = IStream_Write(stm, table_transform_data[i].data,
3071                           table_transform_data[i].size, &count);
3072         if (FAILED(r) || count != table_transform_data[i].size)
3073             ok(0, "failed to write stream\n");
3074         IStream_Release(stm);
3075     }
3076
3077     IStorage_Release(stg);
3078
3079     set_transform_summary_info();
3080 }
3081
3082 static void test_transformprop(void)
3083 {
3084     UINT r;
3085
3086     CreateDirectoryA("msitest", NULL);
3087     create_file("msitest\\augustus", 500);
3088
3089     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
3090
3091     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3092
3093     r = MsiInstallProductA(msifile, NULL);
3094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3095     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3096     ok(!delete_pf("msitest", FALSE), "File installed\n");
3097
3098     if (0)
3099         generate_transform();
3100     else
3101         generate_transform_manual();
3102
3103     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
3104     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3105     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3106     ok(delete_pf("msitest", FALSE), "File not installed\n");
3107
3108     /* Delete the files in the temp (current) folder */
3109     DeleteFile(msifile);
3110     DeleteFile(msifile2);
3111     DeleteFile(mstfile);
3112     DeleteFile("msitest\\augustus");
3113     RemoveDirectory("msitest");
3114 }
3115
3116 static void test_currentworkingdir(void)
3117 {
3118     UINT r;
3119     CHAR path[MAX_PATH];
3120     LPSTR ptr, ptr2;
3121
3122     CreateDirectoryA("msitest", NULL);
3123     create_file("msitest\\augustus", 500);
3124
3125     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
3126
3127     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3128
3129     CreateDirectoryA("diffdir", NULL);
3130     SetCurrentDirectoryA("diffdir");
3131
3132     sprintf(path, "..\\%s", msifile);
3133     r = MsiInstallProductA(path, NULL);
3134     todo_wine
3135     {
3136         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
3137         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3138         ok(!delete_pf("msitest", FALSE), "File installed\n");
3139     }
3140
3141     sprintf(path, "%s\\%s", CURR_DIR, msifile);
3142     r = MsiInstallProductA(path, NULL);
3143     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3144     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3145     ok(delete_pf("msitest", FALSE), "File not installed\n");
3146
3147     lstrcpyA(path, CURR_DIR);
3148     if (path[lstrlenA(path) - 1] != '\\')
3149         lstrcatA(path, "\\");
3150     lstrcatA(path, "msitest.msi");
3151
3152     ptr2 = strrchr(path, '\\');
3153     *ptr2 = '\0';
3154     ptr = strrchr(path, '\\');
3155     *ptr2 = '\\';
3156     *(ptr++) = '\0';
3157
3158     SetCurrentDirectoryA(path);
3159
3160     r = MsiInstallProductA(ptr, NULL);
3161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3162     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3163     ok(delete_pf("msitest", FALSE), "File not installed\n");
3164
3165     SetCurrentDirectoryA(CURR_DIR);
3166
3167     DeleteFile(msifile);
3168     DeleteFile("msitest\\augustus");
3169     RemoveDirectory("msitest");
3170     RemoveDirectory("diffdir");
3171 }
3172
3173 static void set_admin_summary_info(const CHAR *name)
3174 {
3175     MSIHANDLE db, summary;
3176     UINT r;
3177
3178     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
3179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3180
3181     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
3182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3183
3184     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
3185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3186
3187     /* write the summary changes back to the stream */
3188     r = MsiSummaryInfoPersist(summary);
3189     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3190
3191     MsiCloseHandle(summary);
3192
3193     r = MsiDatabaseCommit(db);
3194     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3195
3196     MsiCloseHandle(db);
3197 }
3198
3199 static void test_admin(void)
3200 {
3201     UINT r;
3202
3203     CreateDirectoryA("msitest", NULL);
3204     create_file("msitest\\augustus", 500);
3205
3206     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
3207     set_admin_summary_info(msifile);
3208
3209     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3210
3211     r = MsiInstallProductA(msifile, NULL);
3212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3213     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3214     ok(!delete_pf("msitest", FALSE), "File installed\n");
3215     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
3216     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
3217
3218     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
3219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3220     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3221     ok(!delete_pf("msitest", FALSE), "File installed\n");
3222     todo_wine
3223     {
3224         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
3225         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
3226     }
3227
3228     DeleteFile(msifile);
3229     DeleteFile("msitest\\augustus");
3230     RemoveDirectory("msitest");
3231 }
3232
3233 static void set_admin_property_stream(LPCSTR file)
3234 {
3235     IStorage *stg;
3236     IStream *stm;
3237     WCHAR fileW[MAX_PATH];
3238     HRESULT hr;
3239     DWORD count;
3240     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
3241
3242     /* AdminProperties */
3243     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
3244     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
3245
3246     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
3247
3248     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
3249     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3250     if (!stg)
3251         return;
3252
3253     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3254     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3255
3256     hr = IStream_Write(stm, data, sizeof(data), &count);
3257     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3258
3259     IStream_Release(stm);
3260     IStorage_Release(stg);
3261 }
3262
3263 static void test_adminprops(void)
3264 {
3265     UINT r;
3266
3267     CreateDirectoryA("msitest", NULL);
3268     create_file("msitest\\augustus", 500);
3269
3270     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
3271     set_admin_summary_info(msifile);
3272     set_admin_property_stream(msifile);
3273
3274     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3275
3276     r = MsiInstallProductA(msifile, NULL);
3277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3278     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
3279     ok(delete_pf("msitest", FALSE), "File installed\n");
3280
3281     DeleteFile(msifile);
3282     DeleteFile("msitest\\augustus");
3283     RemoveDirectory("msitest");
3284 }
3285
3286 static void create_pf(LPCSTR file, BOOL is_file)
3287 {
3288     CHAR path[MAX_PATH];
3289
3290     lstrcpyA(path, PROG_FILES_DIR);
3291     lstrcatA(path, "\\");
3292     lstrcatA(path, file);
3293
3294     if (is_file)
3295         create_file(path, 500);
3296     else
3297         CreateDirectoryA(path, NULL);
3298 }
3299
3300 static void test_removefiles(void)
3301 {
3302     UINT r;
3303
3304     CreateDirectoryA("msitest", NULL);
3305     create_file("msitest\\hydrogen", 500);
3306     create_file("msitest\\helium", 500);
3307     create_file("msitest\\lithium", 500);
3308
3309     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
3310
3311     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3312
3313     r = MsiInstallProductA(msifile, NULL);
3314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3315     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
3316     ok(!pf_exists("msitest\\helium"), "File installed\n");
3317     ok(pf_exists("msitest\\lithium"), "File not installed\n");
3318     ok(pf_exists("msitest"), "File not installed\n");
3319
3320     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3321     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3322     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
3323     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
3324     todo_wine
3325     {
3326         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
3327         ok(delete_pf("msitest", FALSE), "File deleted\n");
3328     }
3329
3330     create_pf("msitest", FALSE);
3331     create_pf("msitest\\hydrogen", TRUE);
3332     create_pf("msitest\\helium", TRUE);
3333     create_pf("msitest\\lithium", TRUE);
3334
3335     r = MsiInstallProductA(msifile, NULL);
3336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3337     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
3338     ok(pf_exists("msitest\\helium"), "File not installed\n");
3339     ok(pf_exists("msitest\\lithium"), "File not installed\n");
3340     ok(pf_exists("msitest"), "File not installed\n");
3341
3342     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3344     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
3345     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
3346     todo_wine
3347     {
3348         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
3349         ok(delete_pf("msitest", FALSE), "File deleted\n");
3350     }
3351
3352     create_pf("msitest", FALSE);
3353     create_pf("msitest\\furlong", TRUE);
3354     create_pf("msitest\\firkin", TRUE);
3355     create_pf("msitest\\fortnight", TRUE);
3356     create_pf("msitest\\becquerel", TRUE);
3357     create_pf("msitest\\dioptre", TRUE);
3358     create_pf("msitest\\attoparsec", TRUE);
3359     create_pf("msitest\\storeys", TRUE);
3360     create_pf("msitest\\block", TRUE);
3361     create_pf("msitest\\siriometer", TRUE);
3362
3363     r = MsiInstallProductA(msifile, NULL);
3364     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3365     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
3366     ok(!pf_exists("msitest\\helium"), "File installed\n");
3367     ok(pf_exists("msitest\\lithium"), "File not installed\n");
3368     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
3369     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
3370     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
3371     ok(pf_exists("msitest"), "File not installed\n");
3372     todo_wine
3373     {
3374         ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
3375         ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
3376         ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
3377         ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
3378         ok(!pf_exists("msitest\\block"), "File not deleted\n");
3379         ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
3380     }
3381
3382     create_pf("msitest\\furlong", TRUE);
3383     create_pf("msitest\\firkin", TRUE);
3384     create_pf("msitest\\fortnight", TRUE);
3385     create_pf("msitest\\storeys", TRUE);
3386     create_pf("msitest\\block", TRUE);
3387     create_pf("msitest\\siriometer", TRUE);
3388
3389     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3390     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3391     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
3392     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
3393     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
3394     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
3395     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
3396     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
3397     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
3398     todo_wine
3399     {
3400         ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
3401         ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
3402         ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
3403         ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
3404         ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
3405     }
3406     ok(delete_pf("msitest", FALSE), "File deleted\n");
3407
3408     DeleteFile(msifile);
3409     DeleteFile("msitest\\hydrogen");
3410     DeleteFile("msitest\\helium");
3411     DeleteFile("msitest\\lithium");
3412     RemoveDirectory("msitest");
3413 }
3414
3415 static void test_movefiles(void)
3416 {
3417     UINT r;
3418     char props[MAX_PATH];
3419
3420     CreateDirectoryA("msitest", NULL);
3421     create_file("msitest\\augustus", 100);
3422     create_file("cameroon", 100);
3423     create_file("djibouti", 100);
3424     create_file("egypt", 100);
3425     create_file("finland", 100);
3426     create_file("gambai", 100);
3427     create_file("honduras", 100);
3428     create_file("msitest\\india", 100);
3429     create_file("japan", 100);
3430     create_file("kenya", 100);
3431     CreateDirectoryA("latvia", NULL);
3432     create_file("nauru", 100);
3433     create_file("apple", 100);
3434     create_file("application", 100);
3435     create_file("ape", 100);
3436     create_file("foo", 100);
3437     create_file("fao", 100);
3438     create_file("fbod", 100);
3439     create_file("budding", 100);
3440     create_file("buddy", 100);
3441     create_file("bud", 100);
3442     create_file("bar", 100);
3443     create_file("bur", 100);
3444     create_file("bird", 100);
3445
3446     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
3447
3448     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3449     MsiEnableLog(INSTALLLOGMODE_VERBOSE | INSTALLLOGMODE_EXTRADEBUG, "log.txt", 0);
3450
3451     /* if the source or dest property is not a full path,
3452      * windows tries to access it as a network resource
3453      */
3454
3455     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
3456             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
3457             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
3458
3459     r = MsiInstallProductA(msifile, props);
3460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3461     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3462     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
3463     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
3464     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
3465     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
3466     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
3467     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
3468     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
3469     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
3470     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
3471     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
3472     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
3473     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
3474     ok(!delete_pf("msitest\\apple", TRUE), "File should not exist\n");
3475     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
3476     ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
3477     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
3478     ok(delete_pf("msitest\\foo", TRUE), "File not moved\n");
3479     ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
3480     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
3481     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
3482     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
3483     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
3484     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
3485     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
3486     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
3487     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
3488     ok(delete_pf("msitest", FALSE), "File not installed\n");
3489     ok(DeleteFileA("cameroon"), "File moved\n");
3490     ok(!DeleteFileA("djibouti"), "File not moved\n");
3491     ok(DeleteFileA("egypt"), "File moved\n");
3492     ok(DeleteFileA("finland"), "File moved\n");
3493     ok(DeleteFileA("gambai"), "File moved\n");
3494     ok(!DeleteFileA("honduras"), "File not moved\n");
3495     ok(DeleteFileA("msitest\\india"), "File moved\n");
3496     ok(DeleteFileA("japan"), "File moved\n");
3497     ok(!DeleteFileA("kenya"), "File not moved\n");
3498     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
3499     ok(!DeleteFileA("nauru"), "File not moved\n");
3500     ok(!DeleteFileA("apple"), "File not moved\n");
3501     ok(!DeleteFileA("application"), "File not moved\n");
3502     ok(DeleteFileA("ape"), "File moved\n");
3503     ok(!DeleteFileA("foo"), "File not moved\n");
3504     ok(!DeleteFileA("fao"), "File not moved\n");
3505     ok(DeleteFileA("fbod"), "File moved\n");
3506     ok(!DeleteFileA("budding"), "File not moved\n");
3507     ok(!DeleteFileA("buddy"), "File not moved\n");
3508     ok(DeleteFileA("bud"), "File moved\n");
3509     ok(!DeleteFileA("bar"), "File not moved\n");
3510     ok(!DeleteFileA("bur"), "File not moved\n");
3511     ok(DeleteFileA("bird"), "File moved\n");
3512
3513     DeleteFile("msitest\\augustus");
3514     RemoveDirectory("msitest");
3515     DeleteFile(msifile);
3516 }
3517
3518 static void test_missingcab(void)
3519 {
3520     UINT r;
3521
3522     CreateDirectoryA("msitest", NULL);
3523     create_file("msitest\\augustus", 500);
3524     create_file("maximus", 500);
3525
3526     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
3527
3528     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3529
3530     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3531
3532     create_pf("msitest", FALSE);
3533     create_pf("msitest\\caesar", TRUE);
3534
3535     r = MsiInstallProductA(msifile, NULL);
3536     todo_wine
3537     {
3538         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3539     }
3540     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3541     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3542     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3543     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
3544     ok(delete_pf("msitest", FALSE), "File not installed\n");
3545
3546     create_pf("msitest", FALSE);
3547     create_pf("msitest\\caesar", TRUE);
3548     create_pf("msitest\\gaius", TRUE);
3549
3550     r = MsiInstallProductA(msifile, "GAIUS=1");
3551     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3552     todo_wine
3553     {
3554         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
3555         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3556     }
3557     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
3558     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
3559     ok(delete_pf("msitest", FALSE), "File not installed\n");
3560
3561     DeleteFile("msitest\\augustus");
3562     RemoveDirectory("msitest");
3563     DeleteFile("maximus");
3564     DeleteFile("test1.cab");
3565     DeleteFile(msifile);
3566 }
3567
3568 START_TEST(install)
3569 {
3570     DWORD len;
3571     char temp_path[MAX_PATH], prev_path[MAX_PATH];
3572
3573     init_functionpointers();
3574
3575     GetCurrentDirectoryA(MAX_PATH, prev_path);
3576     GetTempPath(MAX_PATH, temp_path);
3577     SetCurrentDirectoryA(temp_path);
3578
3579     lstrcpyA(CURR_DIR, temp_path);
3580     len = lstrlenA(CURR_DIR);
3581
3582     if(len && (CURR_DIR[len - 1] == '\\'))
3583         CURR_DIR[len - 1] = 0;
3584
3585     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
3586
3587     test_MsiInstallProduct();
3588     test_MsiSetComponentState();
3589     test_packagecoltypes();
3590     test_continuouscabs();
3591     test_caborder();
3592     test_mixedmedia();
3593     test_samesequence();
3594     test_uiLevelFlags();
3595     test_readonlyfile();
3596     test_setdirproperty();
3597     test_cabisextracted();
3598     test_concurrentinstall();
3599     test_setpropertyfolder();
3600     test_publish();
3601     test_publishsourcelist();
3602     test_transformprop();
3603     test_currentworkingdir();
3604     test_admin();
3605     test_adminprops();
3606     test_removefiles();
3607     test_movefiles();
3608     test_missingcab();
3609
3610     SetCurrentDirectoryA(prev_path);
3611 }