msi: Don't enable a feature's components if that feature is disabled.
[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 *pMsiSourceListEnumSourcesA)
38     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
39 static UINT (WINAPI *pMsiSourceListGetInfoA)
40     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
41
42 static const char *msifile = "msitest.msi";
43 static const char *msifile2 = "winetest2.msi";
44 static const char *mstfile = "winetest.mst";
45 static CHAR CURR_DIR[MAX_PATH];
46 static CHAR PROG_FILES_DIR[MAX_PATH];
47 static CHAR COMMON_FILES_DIR[MAX_PATH];
48
49 /* msi database data */
50
51 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
52                                     "s72\tS38\ts72\ti2\tS255\tS72\n"
53                                     "Component\tComponent\n"
54                                     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
55                                     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
56                                     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\t\tone.txt\n"
57                                     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
58                                     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
59                                     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
60                                     "component\t\tMSITESTDIR\t0\t1\tfile\n"
61                                     "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
62
63 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
64                                     "s72\tS72\tl255\n"
65                                     "Directory\tDirectory\n"
66                                     "CABOUTDIR\tMSITESTDIR\tcabout\n"
67                                     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
68                                     "FIRSTDIR\tMSITESTDIR\tfirst\n"
69                                     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
70                                     "NEWDIR\tCABOUTDIR\tnew\n"
71                                     "ProgramFilesFolder\tTARGETDIR\t.\n"
72                                     "TARGETDIR\t\tSourceDir";
73
74 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
75                                   "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
76                                   "Feature\tFeature\n"
77                                   "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
78                                   "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
79                                   "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
80                                   "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
81                                   "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
82                                   "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
83                                   "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
84
85 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
86                                        "s38\ts72\n"
87                                        "FeatureComponents\tFeature_\tComponent_\n"
88                                        "Five\tFive\n"
89                                        "Four\tFour\n"
90                                        "One\tOne\n"
91                                        "Three\tThree\n"
92                                        "Two\tTwo\n"
93                                        "feature\tcomponent\n"
94                                        "service_feature\tservice_comp\n";
95
96 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
97                                "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
98                                "File\tFile\n"
99                                "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
100                                "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
101                                "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
102                                "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
103                                "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
104                                "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
105                                "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
106
107 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
108                                            "s72\tS255\tI2\n"
109                                            "InstallExecuteSequence\tAction\n"
110                                            "AllocateRegistrySpace\tNOT Installed\t1550\n"
111                                            "CostFinalize\t\t1000\n"
112                                            "CostInitialize\t\t800\n"
113                                            "FileCost\t\t900\n"
114                                            "ResolveSource\t\t950\n"
115                                            "MoveFiles\t\t1700\n"
116                                            "InstallFiles\t\t4000\n"
117                                            "DuplicateFiles\t\t4500\n"
118                                            "InstallServices\t\t5000\n"
119                                            "InstallFinalize\t\t6600\n"
120                                            "InstallInitialize\t\t1500\n"
121                                            "InstallValidate\t\t1400\n"
122                                            "LaunchConditions\t\t100\n"
123                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
124
125 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
126                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
127                                 "Media\tDiskId\n"
128                                 "1\t3\t\t\tDISK1\t\n"
129                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
130
131 static const CHAR property_dat[] = "Property\tValue\n"
132                                    "s72\tl0\n"
133                                    "Property\tProperty\n"
134                                    "DefaultUIFont\tDlgFont8\n"
135                                    "HASUIRUN\t0\n"
136                                    "INSTALLLEVEL\t3\n"
137                                    "InstallMode\tTypical\n"
138                                    "Manufacturer\tWine\n"
139                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
140                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
141                                    "ProductID\tnone\n"
142                                    "ProductLanguage\t1033\n"
143                                    "ProductName\tMSITEST\n"
144                                    "ProductVersion\t1.1.1\n"
145                                    "PROMPTROLLBACKCOST\tP\n"
146                                    "Setup\tSetup\n"
147                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
148                                    "AdminProperties\tPOSTADMIN\n"
149                                    "ROOTDRIVE\tC:\\\n"
150                                    "SERVNAME\tTestService\n"
151                                    "SERVDISP\tTestServiceDisp\n";
152
153 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
154                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
155                                    "Registry\tRegistry\n"
156                                    "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
157                                    "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
158                                    "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
159                                    "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
160
161 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
162                                           "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
163                                           "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
164                                           "ServiceInstall\tServiceInstall\n"
165                                           "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
166
167 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
168                                           "s72\tl255\ti2\tL255\tI2\ts72\n"
169                                           "ServiceControl\tServiceControl\n"
170                                           "ServiceControl\tTestService\t8\t\t0\tservice_comp";
171
172 /* tables for test_continuouscabs */
173 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
174                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
175                                        "Component\tComponent\n"
176                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
177                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
178                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
179
180 static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
181                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
182                                         "Component\tComponent\n"
183                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
184                                         "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
185                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
186
187 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
188                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
189                                      "Feature\tFeature\n"
190                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
191
192 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
193                                           "s38\ts72\n"
194                                           "FeatureComponents\tFeature_\tComponent_\n"
195                                           "feature\tmaximus\n"
196                                           "feature\taugustus\n"
197                                           "feature\tcaesar";
198
199 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
200                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
201                                   "File\tFile\n"
202                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
203                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
204                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
205
206 static const CHAR cc2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
207                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
208                                    "File\tFile\n"
209                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
210                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
211                                    "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
212                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
213
214 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
215                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
216                                    "Media\tDiskId\n"
217                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
218                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
219                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
220
221 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
222                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
223                                   "File\tFile\n"
224                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
225                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
226                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
227
228 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
229                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
230                                    "Media\tDiskId\n"
231                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
232                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
233                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
234
235 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
236                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
237                                     "Media\tDiskId\n"
238                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
239                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
240                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
241
242 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
243                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
244                                   "File\tFile\n"
245                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
246                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
247                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
248
249 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
250                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
251                                    "Media\tDiskId\n"
252                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
253
254 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
255                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
256                                    "Media\tDiskId\n"
257                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
258                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
259                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
260
261 /* tables for test_uiLevelFlags */
262 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
263                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
264                                        "Component\tComponent\n"
265                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
266                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
267                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
268
269 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
270                                            "s72\tS255\tI2\n"
271                                            "InstallUISequence\tAction\n"
272                                            "SetUIProperty\t\t5\n"
273                                            "ExecuteAction\t\t1100\n";
274
275 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
276                                            "s72\ti2\tS64\tS0\tS255\n"
277                                            "CustomAction\tAction\n"
278                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
279
280 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
281                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
282                                         "Component\tComponent\n"
283                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
284
285 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
286                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
287                                       "Feature\tFeature\n"
288                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
289                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
290
291 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
292                                            "s38\ts72\n"
293                                            "FeatureComponents\tFeature_\tComponent_\n"
294                                            "feature\tmaximus\n"
295                                            "montecristo\tmaximus";
296
297 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
298                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
299                                    "File\tFile\n"
300                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
301
302 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
303                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
304                                     "Media\tDiskId\n"
305                                     "1\t1\t\t\tDISK1\t\n";
306
307 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
308                                                "s72\tS255\tI2\n"
309                                                "InstallExecuteSequence\tAction\n"
310                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
311                                                "CostFinalize\t\t1000\n"
312                                                "CostInitialize\t\t800\n"
313                                                "FileCost\t\t900\n"
314                                                "InstallFiles\t\t4000\n"
315                                                "InstallFinalize\t\t6600\n"
316                                                "InstallInitialize\t\t1500\n"
317                                                "InstallValidate\t\t1400\n"
318                                                "LaunchConditions\t\t100\n"
319                                                "SetDirProperty\t\t950";
320
321 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
322                                             "s72\ti2\tS64\tS0\tS255\n"
323                                             "CustomAction\tAction\n"
324                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
325
326 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
327                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
328                                         "Component\tComponent\n"
329                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
330                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
331                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
332                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
333
334 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
335                                            "s38\ts72\n"
336                                            "FeatureComponents\tFeature_\tComponent_\n"
337                                            "feature\tmaximus\n"
338                                            "feature\taugustus\n"
339                                            "feature\tcaesar\n"
340                                            "feature\tgaius";
341
342 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
343                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
344                                    "File\tFile\n"
345                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
346                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
347                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
348                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
349
350 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
351                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
352                                     "Media\tDiskId\n"
353                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
354                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
355                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
356
357 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
358                                               "s72\tS255\tI2\n"
359                                               "InstallExecuteSequence\tAction\n"
360                                               "CostFinalize\t\t1000\n"
361                                               "CostInitialize\t\t800\n"
362                                               "FileCost\t\t900\n"
363                                               "InstallFiles\t\t4000\n"
364                                               "InstallServices\t\t5000\n"
365                                               "InstallFinalize\t\t6600\n"
366                                               "InstallInitialize\t\t1500\n"
367                                               "RunInstall\t\t1600\n"
368                                               "InstallValidate\t\t1400\n"
369                                               "LaunchConditions\t\t100";
370
371 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
372                                             "s72\ti2\tS64\tS0\tS255\n"
373                                             "CustomAction\tAction\n"
374                                             "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
375
376 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
377                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
378                                        "Component\tComponent\n"
379                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
380
381 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
382                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
383                                         "Component\tComponent\n"
384                                         "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
385
386 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
387                                            "s38\ts72\n"
388                                            "FeatureComponents\tFeature_\tComponent_\n"
389                                            "feature\taugustus";
390
391 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
392                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
393                                    "File\tFile\n"
394                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
395
396 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
397                                             "s72\ti2\tS64\tS0\tS255\n"
398                                             "CustomAction\tAction\n"
399                                             "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
400
401 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
402                                                "s72\tS255\tI2\n"
403                                                "InstallExecuteSequence\tAction\n"
404                                                "CostFinalize\t\t1000\n"
405                                                "CostInitialize\t\t800\n"
406                                                "FileCost\t\t900\n"
407                                                "SetFolderProp\t\t950\n"
408                                                "InstallFiles\t\t4000\n"
409                                                "InstallServices\t\t5000\n"
410                                                "InstallFinalize\t\t6600\n"
411                                                "InstallInitialize\t\t1500\n"
412                                                "InstallValidate\t\t1400\n"
413                                                "LaunchConditions\t\t100";
414
415 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
416                                              "s72\tS255\tI2\n"
417                                              "InstallUISequence\tAction\n"
418                                              "CostInitialize\t\t800\n"
419                                              "FileCost\t\t900\n"
420                                              "CostFinalize\t\t1000\n"
421                                              "ExecuteAction\t\t1100\n";
422
423 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
424                                               "s72\tS255\tI2\n"
425                                               "InstallExecuteSequence\tAction\n"
426                                               "ValidateProductID\t\t700\n"
427                                               "CostInitialize\t\t800\n"
428                                               "FileCost\t\t900\n"
429                                               "CostFinalize\t\t1000\n"
430                                               "InstallValidate\t\t1400\n"
431                                               "InstallInitialize\t\t1500\n"
432                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
433                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
434                                               "RemoveFiles\t\t3500\n"
435                                               "InstallFiles\t\t4000\n"
436                                               "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
437                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
438                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
439                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
440                                               "InstallFinalize\t\t6600";
441
442 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
443                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
444                                        "Component\tComponent\n"
445                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
446
447 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
448                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
449                                         "Component\tComponent\n"
450                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
451
452 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
453                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
454                                         "Component\tComponent\n"
455                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
456
457 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
458                                             "s72\ti2\tS64\tS0\tS255\n"
459                                             "CustomAction\tAction\n"
460                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
461
462 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
463                                              "s72\tS255\tI2\n"
464                                              "AdminExecuteSequence\tAction\n"
465                                              "CostFinalize\t\t1000\n"
466                                              "CostInitialize\t\t800\n"
467                                              "FileCost\t\t900\n"
468                                              "SetPOSTADMIN\t\t950\n"
469                                              "InstallFiles\t\t4000\n"
470                                              "InstallFinalize\t\t6600\n"
471                                              "InstallInitialize\t\t1500\n"
472                                              "InstallValidate\t\t1400\n"
473                                              "LaunchConditions\t\t100";
474
475 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
476                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
477                                         "Component\tComponent\n"
478                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718\taugustus\n";
479
480 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
481                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
482                                         "Component\tComponent\n"
483                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
484                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
485                                         "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
486
487 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
488                                            "s38\ts72\n"
489                                            "FeatureComponents\tFeature_\tComponent_\n"
490                                            "feature\thydrogen\n"
491                                            "feature\thelium\n"
492                                            "feature\tlithium";
493
494 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
495                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
496                                    "File\tFile\n"
497                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
498                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
499                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
500
501 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
502                                                "s72\tS255\tI2\n"
503                                                "InstallExecuteSequence\tAction\n"
504                                                "ValidateProductID\t\t700\n"
505                                                "CostInitialize\t\t800\n"
506                                                "FileCost\t\t900\n"
507                                                "CostFinalize\t\t1000\n"
508                                                "InstallValidate\t\t1400\n"
509                                                "InstallInitialize\t\t1500\n"
510                                                "ProcessComponents\t\t1600\n"
511                                                "UnpublishFeatures\t\t1800\n"
512                                                "RemoveFiles\t\t3500\n"
513                                                "InstallFiles\t\t4000\n"
514                                                "RegisterProduct\t\t6100\n"
515                                                "PublishFeatures\t\t6300\n"
516                                                "PublishProduct\t\t6400\n"
517                                                "InstallFinalize\t\t6600";
518
519 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
520                                            "s72\ts72\tS255\ts72\tI2\n"
521                                            "RemoveFile\tFileKey\n"
522                                            "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
523                                            "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
524                                            "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
525                                            "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
526                                            "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
527                                            "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
528                                            "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
529                                            "block\thelium\tblock\tMSITESTDIR\t3\n"
530                                            "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n";
531
532 static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
533                                         "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
534                                         "MoveFile\tFileKey\n"
535                                         "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
536                                         "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
537                                         "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
538                                         "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
539                                         "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
540                                         "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
541                                         "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
542                                         "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
543                                         "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
544                                         "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
545                                         "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
546                                         "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
547                                         "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
548                                         "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
549                                         "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
550                                         "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
551                                         "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
552
553 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
554                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
555                                         "Component\tComponent\n"
556                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
557                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
558                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
559                                         "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
560
561 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
562                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
563                                   "File\tFile\n"
564                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
565                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
566                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
567                                   "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
568
569 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
570                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
571                                    "Media\tDiskId\n"
572                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
573                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
574                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
575                                    "4\t4\t\ttest3.cab\tDISK3\t\n";
576
577 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
578                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
579                                        "MsiFileHash\tFile_\n"
580                                        "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
581
582 static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
583                                        "s72\tS72\tl255\n"
584                                        "Directory\tDirectory\n"
585                                        "THIS\tMSITESTDIR\tthis\n"
586                                        "DOESNOT\tTHIS\tdoesnot\n"
587                                        "NONEXISTENT\tDOESNOT\texist\n"
588                                        "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
589                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
590                                        "TARGETDIR\t\tSourceDir";
591
592 static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
593                                             "s72\ts72\ts72\tS255\tS72\n"
594                                             "DuplicateFile\tFileKey\n"
595                                             "maximus\tmaximus\tmaximus\taugustus\t\n"
596                                             "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n";
597
598 static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
599                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
600                                         "Component\tComponent\n"
601                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
602
603 static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
604                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
605                                        "Registry\tRegistry\n"
606                                        "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
607
608 static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
609                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
610                                          "Component\tComponent\n"
611                                          "augustus\t\tMSITESTDIR\t0\tMYPROP=42\taugustus\n";
612
613 static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
614                                                 "s72\tS255\tI2\n"
615                                                 "InstallExecuteSequence\tAction\n"
616                                                 "ValidateProductID\t\t700\n"
617                                                 "GoodSetProperty\t\t725\n"
618                                                 "BadSetProperty\t\t750\n"
619                                                 "CostInitialize\t\t800\n"
620                                                 "FileCost\t\t900\n"
621                                                 "CostFinalize\t\t1000\n"
622                                                 "InstallValidate\t\t1400\n"
623                                                 "InstallInitialize\t\t1500\n"
624                                                 "InstallFiles\t\t4000\n"
625                                                 "InstallFinalize\t\t6600";
626
627 static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
628                                              "s72\ti2\tS64\tS0\n"
629                                              "CustomAction\tAction\n"
630                                              "GoodSetProperty\t51\tMYPROP\t42\n"
631                                              "BadSetProperty\t51\t\tMYPROP\n";
632
633 static const CHAR is_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
634                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
635                                      "Feature\tFeature\n"
636                                      "one\t\t\t\t2\t1\t\t0\n" /* favorLocal */
637                                      "two\t\t\t\t2\t1\t\t1\n" /* favorSource */
638                                      "three\t\t\t\t2\t1\t\t4\n" /* favorAdvertise */
639                                      "four\t\t\t\t2\t0\t\t0"; /* disabled */
640
641 static const CHAR is_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
642                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
643                                        "Component\tComponent\n"
644                                        "alpha\t\tMSITESTDIR\t0\t\talpha_file\n" /* favorLocal:Local */
645                                        "beta\t\tMSITESTDIR\t1\t\tbeta_file\n" /* favorLocal:Source */
646                                        "gamma\t\tMSITESTDIR\t2\t\tgamma_file\n" /* favorLocal:Optional */
647                                        "theta\t\tMSITESTDIR\t0\t\ttheta_file\n" /* favorSource:Local */
648                                        "delta\t\tMSITESTDIR\t1\t\tdelta_file\n" /* favorSource:Source */
649                                        "epsilon\t\tMSITESTDIR\t2\t\tepsilon_file\n" /* favorSource:Optional */
650                                        "zeta\t\tMSITESTDIR\t0\t\tzeta_file\n" /* favorAdvertise:Local */
651                                        "iota\t\tMSITESTDIR\t1\t\tiota_file\n" /* favorAdvertise:Source */
652                                        "eta\t\tMSITESTDIR\t2\t\teta_file\n" /* favorAdvertise:Optional */
653                                        "kappa\t\tMSITESTDIR\t0\t\tkappa_file\n" /* disabled:Local */
654                                        "lambda\t\tMSITESTDIR\t1\t\tlambda_file\n" /* disabled:Source */
655                                        "mu\t\tMSITESTDIR\t2\t\tmu_file\n"; /* disabled:Optional */
656
657 static const CHAR is_feature_comp_dat[] = "Feature_\tComponent_\n"
658                                           "s38\ts72\n"
659                                           "FeatureComponents\tFeature_\tComponent_\n"
660                                           "one\talpha\n"
661                                           "one\tbeta\n"
662                                           "one\tgamma\n"
663                                           "two\ttheta\n"
664                                           "two\tdelta\n"
665                                           "two\tepsilon\n"
666                                           "three\tzeta\n"
667                                           "three\tiota\n"
668                                           "three\teta\n"
669                                           "four\tkappa\n"
670                                           "four\tlambda\n"
671                                           "four\tmu";
672
673 static const CHAR is_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
674                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
675                                   "File\tFile\n"
676                                   "alpha_file\talpha\talpha\t500\t\t\t8192\t1\n"
677                                   "beta_file\tbeta\tbeta\t500\t\t\t8291\t2\n"
678                                   "gamma_file\tgamma\tgamma\t500\t\t\t8192\t3\n"
679                                   "theta_file\ttheta\ttheta\t500\t\t\t8192\t4\n"
680                                   "delta_file\tdelta\tdelta\t500\t\t\t8192\t5\n"
681                                   "epsilon_file\tepsilon\tepsilon\t500\t\t\t8192\t6\n"
682                                   "zeta_file\tzeta\tzeta\t500\t\t\t8192\t7\n"
683                                   "iota_file\tiota\tiota\t500\t\t\t8192\t8\n"
684                                   "eta_file\teta\teta\t500\t\t\t8192\t9\n"
685                                   "kappa_file\tkappa\tkappa\t500\t\t\t8192\t10\n"
686                                   "lambda_file\tlambda\tlambda\t500\t\t\t8192\t11\n"
687                                   "mu_file\tmu\tmu\t500\t\t\t8192\t12";
688
689 static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
690                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
691                                    "Media\tDiskId\n"
692                                    "1\t12\t\t\tDISK1\t\n";
693
694 typedef struct _msi_table
695 {
696     const CHAR *filename;
697     const CHAR *data;
698     int size;
699 } msi_table;
700
701 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
702
703 static const msi_table tables[] =
704 {
705     ADD_TABLE(component),
706     ADD_TABLE(directory),
707     ADD_TABLE(feature),
708     ADD_TABLE(feature_comp),
709     ADD_TABLE(file),
710     ADD_TABLE(install_exec_seq),
711     ADD_TABLE(media),
712     ADD_TABLE(property),
713     ADD_TABLE(registry),
714     ADD_TABLE(service_install),
715     ADD_TABLE(service_control)
716 };
717
718 static const msi_table cc_tables[] =
719 {
720     ADD_TABLE(cc_component),
721     ADD_TABLE(directory),
722     ADD_TABLE(cc_feature),
723     ADD_TABLE(cc_feature_comp),
724     ADD_TABLE(cc_file),
725     ADD_TABLE(install_exec_seq),
726     ADD_TABLE(cc_media),
727     ADD_TABLE(property),
728 };
729
730 static const msi_table cc2_tables[] =
731 {
732     ADD_TABLE(cc2_component),
733     ADD_TABLE(directory),
734     ADD_TABLE(cc_feature),
735     ADD_TABLE(cc_feature_comp),
736     ADD_TABLE(cc2_file),
737     ADD_TABLE(install_exec_seq),
738     ADD_TABLE(cc_media),
739     ADD_TABLE(property),
740 };
741
742 static const msi_table co_tables[] =
743 {
744     ADD_TABLE(cc_component),
745     ADD_TABLE(directory),
746     ADD_TABLE(cc_feature),
747     ADD_TABLE(cc_feature_comp),
748     ADD_TABLE(co_file),
749     ADD_TABLE(install_exec_seq),
750     ADD_TABLE(co_media),
751     ADD_TABLE(property),
752 };
753
754 static const msi_table co2_tables[] =
755 {
756     ADD_TABLE(cc_component),
757     ADD_TABLE(directory),
758     ADD_TABLE(cc_feature),
759     ADD_TABLE(cc_feature_comp),
760     ADD_TABLE(cc_file),
761     ADD_TABLE(install_exec_seq),
762     ADD_TABLE(co2_media),
763     ADD_TABLE(property),
764 };
765
766 static const msi_table mm_tables[] =
767 {
768     ADD_TABLE(cc_component),
769     ADD_TABLE(directory),
770     ADD_TABLE(cc_feature),
771     ADD_TABLE(cc_feature_comp),
772     ADD_TABLE(mm_file),
773     ADD_TABLE(install_exec_seq),
774     ADD_TABLE(mm_media),
775     ADD_TABLE(property),
776 };
777
778 static const msi_table ss_tables[] =
779 {
780     ADD_TABLE(cc_component),
781     ADD_TABLE(directory),
782     ADD_TABLE(cc_feature),
783     ADD_TABLE(cc_feature_comp),
784     ADD_TABLE(cc_file),
785     ADD_TABLE(install_exec_seq),
786     ADD_TABLE(ss_media),
787     ADD_TABLE(property),
788 };
789
790 static const msi_table ui_tables[] =
791 {
792     ADD_TABLE(ui_component),
793     ADD_TABLE(directory),
794     ADD_TABLE(cc_feature),
795     ADD_TABLE(cc_feature_comp),
796     ADD_TABLE(cc_file),
797     ADD_TABLE(install_exec_seq),
798     ADD_TABLE(ui_install_ui_seq),
799     ADD_TABLE(ui_custom_action),
800     ADD_TABLE(cc_media),
801     ADD_TABLE(property),
802 };
803
804 static const msi_table rof_tables[] =
805 {
806     ADD_TABLE(rof_component),
807     ADD_TABLE(directory),
808     ADD_TABLE(rof_feature),
809     ADD_TABLE(rof_feature_comp),
810     ADD_TABLE(rof_file),
811     ADD_TABLE(install_exec_seq),
812     ADD_TABLE(rof_media),
813     ADD_TABLE(property),
814 };
815
816 static const msi_table sdp_tables[] =
817 {
818     ADD_TABLE(rof_component),
819     ADD_TABLE(directory),
820     ADD_TABLE(rof_feature),
821     ADD_TABLE(rof_feature_comp),
822     ADD_TABLE(rof_file),
823     ADD_TABLE(sdp_install_exec_seq),
824     ADD_TABLE(sdp_custom_action),
825     ADD_TABLE(rof_media),
826     ADD_TABLE(property),
827 };
828
829 static const msi_table cie_tables[] =
830 {
831     ADD_TABLE(cie_component),
832     ADD_TABLE(directory),
833     ADD_TABLE(cc_feature),
834     ADD_TABLE(cie_feature_comp),
835     ADD_TABLE(cie_file),
836     ADD_TABLE(install_exec_seq),
837     ADD_TABLE(cie_media),
838     ADD_TABLE(property),
839 };
840
841 static const msi_table ci_tables[] =
842 {
843     ADD_TABLE(ci_component),
844     ADD_TABLE(directory),
845     ADD_TABLE(rof_feature),
846     ADD_TABLE(rof_feature_comp),
847     ADD_TABLE(rof_file),
848     ADD_TABLE(ci_install_exec_seq),
849     ADD_TABLE(rof_media),
850     ADD_TABLE(property),
851     ADD_TABLE(ci_custom_action),
852 };
853
854 static const msi_table ci2_tables[] =
855 {
856     ADD_TABLE(ci2_component),
857     ADD_TABLE(directory),
858     ADD_TABLE(rof_feature),
859     ADD_TABLE(ci2_feature_comp),
860     ADD_TABLE(ci2_file),
861     ADD_TABLE(install_exec_seq),
862     ADD_TABLE(rof_media),
863     ADD_TABLE(property),
864 };
865
866 static const msi_table spf_tables[] =
867 {
868     ADD_TABLE(ci_component),
869     ADD_TABLE(directory),
870     ADD_TABLE(rof_feature),
871     ADD_TABLE(rof_feature_comp),
872     ADD_TABLE(rof_file),
873     ADD_TABLE(spf_install_exec_seq),
874     ADD_TABLE(rof_media),
875     ADD_TABLE(property),
876     ADD_TABLE(spf_custom_action),
877     ADD_TABLE(spf_install_ui_seq),
878 };
879
880 static const msi_table pp_tables[] =
881 {
882     ADD_TABLE(ci_component),
883     ADD_TABLE(directory),
884     ADD_TABLE(rof_feature),
885     ADD_TABLE(rof_feature_comp),
886     ADD_TABLE(rof_file),
887     ADD_TABLE(pp_install_exec_seq),
888     ADD_TABLE(rof_media),
889     ADD_TABLE(property),
890 };
891
892 static const msi_table tp_tables[] =
893 {
894     ADD_TABLE(tp_component),
895     ADD_TABLE(directory),
896     ADD_TABLE(rof_feature),
897     ADD_TABLE(ci2_feature_comp),
898     ADD_TABLE(ci2_file),
899     ADD_TABLE(install_exec_seq),
900     ADD_TABLE(rof_media),
901     ADD_TABLE(property),
902 };
903
904 static const msi_table cwd_tables[] =
905 {
906     ADD_TABLE(cwd_component),
907     ADD_TABLE(directory),
908     ADD_TABLE(rof_feature),
909     ADD_TABLE(ci2_feature_comp),
910     ADD_TABLE(ci2_file),
911     ADD_TABLE(install_exec_seq),
912     ADD_TABLE(rof_media),
913     ADD_TABLE(property),
914 };
915
916 static const msi_table adm_tables[] =
917 {
918     ADD_TABLE(adm_component),
919     ADD_TABLE(directory),
920     ADD_TABLE(rof_feature),
921     ADD_TABLE(ci2_feature_comp),
922     ADD_TABLE(ci2_file),
923     ADD_TABLE(install_exec_seq),
924     ADD_TABLE(rof_media),
925     ADD_TABLE(property),
926     ADD_TABLE(adm_custom_action),
927     ADD_TABLE(adm_admin_exec_seq),
928 };
929
930 static const msi_table amp_tables[] =
931 {
932     ADD_TABLE(amp_component),
933     ADD_TABLE(directory),
934     ADD_TABLE(rof_feature),
935     ADD_TABLE(ci2_feature_comp),
936     ADD_TABLE(ci2_file),
937     ADD_TABLE(install_exec_seq),
938     ADD_TABLE(rof_media),
939     ADD_TABLE(property),
940 };
941
942 static const msi_table rem_tables[] =
943 {
944     ADD_TABLE(rem_component),
945     ADD_TABLE(directory),
946     ADD_TABLE(rof_feature),
947     ADD_TABLE(rem_feature_comp),
948     ADD_TABLE(rem_file),
949     ADD_TABLE(rem_install_exec_seq),
950     ADD_TABLE(rof_media),
951     ADD_TABLE(property),
952     ADD_TABLE(rem_remove_files),
953 };
954
955 static const msi_table mov_tables[] =
956 {
957     ADD_TABLE(cwd_component),
958     ADD_TABLE(directory),
959     ADD_TABLE(rof_feature),
960     ADD_TABLE(ci2_feature_comp),
961     ADD_TABLE(ci2_file),
962     ADD_TABLE(install_exec_seq),
963     ADD_TABLE(rof_media),
964     ADD_TABLE(property),
965     ADD_TABLE(mov_move_file),
966 };
967
968 static const msi_table mc_tables[] =
969 {
970     ADD_TABLE(mc_component),
971     ADD_TABLE(directory),
972     ADD_TABLE(cc_feature),
973     ADD_TABLE(cie_feature_comp),
974     ADD_TABLE(mc_file),
975     ADD_TABLE(install_exec_seq),
976     ADD_TABLE(mc_media),
977     ADD_TABLE(property),
978     ADD_TABLE(mc_file_hash),
979 };
980
981 static const msi_table df_tables[] =
982 {
983     ADD_TABLE(rof_component),
984     ADD_TABLE(df_directory),
985     ADD_TABLE(rof_feature),
986     ADD_TABLE(rof_feature_comp),
987     ADD_TABLE(rof_file),
988     ADD_TABLE(install_exec_seq),
989     ADD_TABLE(rof_media),
990     ADD_TABLE(property),
991     ADD_TABLE(df_duplicate_file),
992 };
993
994 static const msi_table wrv_tables[] =
995 {
996     ADD_TABLE(wrv_component),
997     ADD_TABLE(directory),
998     ADD_TABLE(rof_feature),
999     ADD_TABLE(ci2_feature_comp),
1000     ADD_TABLE(ci2_file),
1001     ADD_TABLE(install_exec_seq),
1002     ADD_TABLE(rof_media),
1003     ADD_TABLE(property),
1004     ADD_TABLE(wrv_registry),
1005 };
1006
1007 static const msi_table sf_tables[] =
1008 {
1009     ADD_TABLE(wrv_component),
1010     ADD_TABLE(directory),
1011     ADD_TABLE(rof_feature),
1012     ADD_TABLE(ci2_feature_comp),
1013     ADD_TABLE(ci2_file),
1014     ADD_TABLE(install_exec_seq),
1015     ADD_TABLE(rof_media),
1016     ADD_TABLE(property),
1017 };
1018
1019 static const msi_table ca51_tables[] =
1020 {
1021     ADD_TABLE(ca51_component),
1022     ADD_TABLE(directory),
1023     ADD_TABLE(rof_feature),
1024     ADD_TABLE(ci2_feature_comp),
1025     ADD_TABLE(ci2_file),
1026     ADD_TABLE(ca51_install_exec_seq),
1027     ADD_TABLE(rof_media),
1028     ADD_TABLE(property),
1029     ADD_TABLE(ca51_custom_action),
1030 };
1031
1032 static const msi_table is_tables[] =
1033 {
1034     ADD_TABLE(is_component),
1035     ADD_TABLE(directory),
1036     ADD_TABLE(is_feature),
1037     ADD_TABLE(is_feature_comp),
1038     ADD_TABLE(is_file),
1039     ADD_TABLE(install_exec_seq),
1040     ADD_TABLE(is_media),
1041     ADD_TABLE(property),
1042 };
1043
1044 /* cabinet definitions */
1045
1046 /* make the max size large so there is only one cab file */
1047 #define MEDIA_SIZE          0x7FFFFFFF
1048 #define FOLDER_THRESHOLD    900000
1049
1050 /* the FCI callbacks */
1051
1052 static void *mem_alloc(ULONG cb)
1053 {
1054     return HeapAlloc(GetProcessHeap(), 0, cb);
1055 }
1056
1057 static void mem_free(void *memory)
1058 {
1059     HeapFree(GetProcessHeap(), 0, memory);
1060 }
1061
1062 static BOOL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
1063 {
1064     sprintf(pccab->szCab, pv, pccab->iCab);
1065     return TRUE;
1066 }
1067
1068 static long progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
1069 {
1070     return 0;
1071 }
1072
1073 static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
1074                        BOOL fContinuation, void *pv)
1075 {
1076     return 0;
1077 }
1078
1079 static INT_PTR fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
1080 {
1081     HANDLE handle;
1082     DWORD dwAccess = 0;
1083     DWORD dwShareMode = 0;
1084     DWORD dwCreateDisposition = OPEN_EXISTING;
1085     
1086     dwAccess = GENERIC_READ | GENERIC_WRITE;
1087     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
1088     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1089
1090     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
1091         dwCreateDisposition = OPEN_EXISTING;
1092     else
1093         dwCreateDisposition = CREATE_NEW;
1094
1095     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
1096                          dwCreateDisposition, 0, NULL);
1097
1098     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
1099
1100     return (INT_PTR)handle;
1101 }
1102
1103 static UINT fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1104 {
1105     HANDLE handle = (HANDLE)hf;
1106     DWORD dwRead;
1107     BOOL res;
1108     
1109     res = ReadFile(handle, memory, cb, &dwRead, NULL);
1110     ok(res, "Failed to ReadFile\n");
1111
1112     return dwRead;
1113 }
1114
1115 static UINT fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1116 {
1117     HANDLE handle = (HANDLE)hf;
1118     DWORD dwWritten;
1119     BOOL res;
1120
1121     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
1122     ok(res, "Failed to WriteFile\n");
1123
1124     return dwWritten;
1125 }
1126
1127 static int fci_close(INT_PTR hf, int *err, void *pv)
1128 {
1129     HANDLE handle = (HANDLE)hf;
1130     ok(CloseHandle(handle), "Failed to CloseHandle\n");
1131
1132     return 0;
1133 }
1134
1135 static long fci_seek(INT_PTR hf, long dist, int seektype, int *err, void *pv)
1136 {
1137     HANDLE handle = (HANDLE)hf;
1138     DWORD ret;
1139     
1140     ret = SetFilePointer(handle, dist, NULL, seektype);
1141     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
1142
1143     return ret;
1144 }
1145
1146 static int fci_delete(char *pszFile, int *err, void *pv)
1147 {
1148     BOOL ret = DeleteFileA(pszFile);
1149     ok(ret, "Failed to DeleteFile %s\n", pszFile);
1150
1151     return 0;
1152 }
1153
1154 static void init_functionpointers(void)
1155 {
1156     HMODULE hmsi = GetModuleHandleA("msi.dll");
1157
1158 #define GET_PROC(func) \
1159     p ## func = (void*)GetProcAddress(hmsi, #func); \
1160     if(!p ## func) \
1161       trace("GetProcAddress(%s) failed\n", #func);
1162
1163     GET_PROC(MsiQueryComponentStateA);
1164     GET_PROC(MsiSourceListEnumSourcesA);
1165     GET_PROC(MsiSourceListGetInfoA);
1166
1167 #undef GET_PROC
1168 }
1169
1170 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
1171 {
1172     CHAR buffer[0x20];
1173     UINT r;
1174     DWORD sz;
1175
1176     sz = sizeof buffer;
1177     r = MsiRecordGetString(rec, field, buffer, &sz);
1178     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1179 }
1180
1181 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
1182 {
1183     LPSTR tempname;
1184
1185     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
1186     GetTempFileNameA(".", "xx", 0, tempname);
1187
1188     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
1189     {
1190         lstrcpyA(pszTempName, tempname);
1191         HeapFree(GetProcessHeap(), 0, tempname);
1192         return TRUE;
1193     }
1194
1195     HeapFree(GetProcessHeap(), 0, tempname);
1196
1197     return FALSE;
1198 }
1199
1200 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
1201                              USHORT *pattribs, int *err, void *pv)
1202 {
1203     BY_HANDLE_FILE_INFORMATION finfo;
1204     FILETIME filetime;
1205     HANDLE handle;
1206     DWORD attrs;
1207     BOOL res;
1208
1209     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
1210                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1211
1212     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
1213
1214     res = GetFileInformationByHandle(handle, &finfo);
1215     ok(res, "Expected GetFileInformationByHandle to succeed\n");
1216    
1217     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
1218     FileTimeToDosDateTime(&filetime, pdate, ptime);
1219
1220     attrs = GetFileAttributes(pszName);
1221     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
1222
1223     return (INT_PTR)handle;
1224 }
1225
1226 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
1227 {
1228     char path[MAX_PATH];
1229     char filename[MAX_PATH];
1230
1231     lstrcpyA(path, CURR_DIR);
1232     lstrcatA(path, "\\");
1233     lstrcatA(path, file);
1234
1235     lstrcpyA(filename, file);
1236
1237     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
1238                       progress, get_open_info, compress);
1239 }
1240
1241 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
1242 {
1243     ZeroMemory(pCabParams, sizeof(CCAB));
1244
1245     pCabParams->cb = max_size;
1246     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
1247     pCabParams->setID = 0xbeef;
1248     pCabParams->iCab = 1;
1249     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
1250     lstrcatA(pCabParams->szCabPath, "\\");
1251     lstrcpyA(pCabParams->szCab, name);
1252 }
1253
1254 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
1255 {
1256     CCAB cabParams;
1257     LPCSTR ptr;
1258     HFCI hfci;
1259     ERF erf;
1260     BOOL res;
1261
1262     set_cab_parameters(&cabParams, name, max_size);
1263
1264     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1265                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1266                       get_temp_file, &cabParams, NULL);
1267
1268     ok(hfci != NULL, "Failed to create an FCI context\n");
1269
1270     ptr = files;
1271     while (*ptr)
1272     {
1273         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
1274         ok(res, "Failed to add file: %s\n", ptr);
1275         ptr += lstrlen(ptr) + 1;
1276     }
1277
1278     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1279     ok(res, "Failed to flush the cabinet\n");
1280
1281     res = FCIDestroy(hfci);
1282     ok(res, "Failed to destroy the cabinet\n");
1283 }
1284
1285 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1286 {
1287     HKEY hkey;
1288     DWORD type, size;
1289
1290     if (RegOpenKey(HKEY_LOCAL_MACHINE,
1291                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1292         return FALSE;
1293
1294     size = MAX_PATH;
1295     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1296         RegCloseKey(hkey);
1297         return FALSE;
1298     }
1299
1300     size = MAX_PATH;
1301     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1302         RegCloseKey(hkey);
1303         return FALSE;
1304     }
1305
1306     RegCloseKey(hkey);
1307     return TRUE;
1308 }
1309
1310 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1311 {
1312     HANDLE file;
1313     DWORD written;
1314
1315     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1316     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1317     WriteFile(file, data, strlen(data), &written, NULL);
1318
1319     if (size)
1320     {
1321         SetFilePointer(file, size, NULL, FILE_BEGIN);
1322         SetEndOfFile(file);
1323     }
1324
1325     CloseHandle(file);
1326 }
1327
1328 #define create_file(name, size) create_file_data(name, name, size)
1329
1330 static void create_test_files(void)
1331 {
1332     CreateDirectoryA("msitest", NULL);
1333     create_file("msitest\\one.txt", 100);
1334     CreateDirectoryA("msitest\\first", NULL);
1335     create_file("msitest\\first\\two.txt", 100);
1336     CreateDirectoryA("msitest\\second", NULL);
1337     create_file("msitest\\second\\three.txt", 100);
1338
1339     create_file("four.txt", 100);
1340     create_file("five.txt", 100);
1341     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1342
1343     create_file("msitest\\filename", 100);
1344     create_file("msitest\\service.exe", 100);
1345
1346     DeleteFileA("four.txt");
1347     DeleteFileA("five.txt");
1348 }
1349
1350 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1351 {
1352     CHAR path[MAX_PATH];
1353
1354     lstrcpyA(path, PROG_FILES_DIR);
1355     lstrcatA(path, "\\");
1356     lstrcatA(path, rel_path);
1357
1358     if (is_file)
1359         return DeleteFileA(path);
1360     else
1361         return RemoveDirectoryA(path);
1362 }
1363
1364 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1365 {
1366     CHAR path[MAX_PATH];
1367
1368     lstrcpyA(path, COMMON_FILES_DIR);
1369     lstrcatA(path, "\\");
1370     lstrcatA(path, rel_path);
1371
1372     if (is_file)
1373         return DeleteFileA(path);
1374     else
1375         return RemoveDirectoryA(path);
1376 }
1377
1378 static void delete_test_files(void)
1379 {
1380     DeleteFileA("msitest.msi");
1381     DeleteFileA("msitest.cab");
1382     DeleteFileA("msitest\\second\\three.txt");
1383     DeleteFileA("msitest\\first\\two.txt");
1384     DeleteFileA("msitest\\one.txt");
1385     DeleteFileA("msitest\\service.exe");
1386     DeleteFileA("msitest\\filename");
1387     RemoveDirectoryA("msitest\\second");
1388     RemoveDirectoryA("msitest\\first");
1389     RemoveDirectoryA("msitest");
1390 }
1391
1392 static void write_file(const CHAR *filename, const char *data, int data_size)
1393 {
1394     DWORD size;
1395
1396     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1397                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1398
1399     WriteFile(hf, data, data_size, &size, NULL);
1400     CloseHandle(hf);
1401 }
1402
1403 static void write_msi_summary_info(MSIHANDLE db)
1404 {
1405     MSIHANDLE summary;
1406     UINT r;
1407
1408     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1410
1411     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1413
1414     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1415                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1417
1418     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1420
1421     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1423
1424     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1425     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1426
1427     /* write the summary changes back to the stream */
1428     r = MsiSummaryInfoPersist(summary);
1429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1430
1431     MsiCloseHandle(summary);
1432 }
1433
1434 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1435 {
1436     MSIHANDLE db;
1437     UINT r;
1438     int j;
1439
1440     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1442
1443     /* import the tables into the database */
1444     for (j = 0; j < num_tables; j++)
1445     {
1446         const msi_table *table = &tables[j];
1447
1448         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1449
1450         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1451         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1452
1453         DeleteFileA(table->filename);
1454     }
1455
1456     write_msi_summary_info(db);
1457
1458     r = MsiDatabaseCommit(db);
1459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1460
1461     MsiCloseHandle(db);
1462 }
1463
1464 static void check_service_is_installed(void)
1465 {
1466     SC_HANDLE scm, service;
1467     BOOL res;
1468
1469     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1470     ok(scm != NULL, "Failed to open the SC Manager\n");
1471
1472     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1473     ok(service != NULL, "Failed to open TestService\n");
1474
1475     res = DeleteService(service);
1476     ok(res, "Failed to delete TestService\n");
1477
1478     CloseServiceHandle(service);
1479     CloseServiceHandle(scm);
1480 }
1481
1482 static void test_MsiInstallProduct(void)
1483 {
1484     UINT r;
1485     CHAR path[MAX_PATH];
1486     LONG res;
1487     HKEY hkey;
1488     DWORD num, size, type;
1489     SC_HANDLE scm;
1490
1491     scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
1492     if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1493     {
1494         skip("Services are not implemented, we are most likely on win9x\n");
1495         return;
1496     }
1497     CloseServiceHandle(scm);
1498
1499     create_test_files();
1500     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1501
1502     r = MsiInstallProductA(msifile, NULL);
1503     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1504
1505     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1506     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1507     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1508     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1509     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1510     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1511     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1512     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1513     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1514     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1515     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1516     ok(delete_pf("msitest", FALSE), "File not installed\n");
1517
1518     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1519     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1520
1521     size = MAX_PATH;
1522     type = REG_SZ;
1523     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1525     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1526
1527     size = MAX_PATH;
1528     type = REG_SZ;
1529     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1530     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1531
1532     size = sizeof(num);
1533     type = REG_DWORD;
1534     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1536     ok(num == 314, "Expected 314, got %d\n", num);
1537
1538     size = MAX_PATH;
1539     type = REG_SZ;
1540     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1541     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1542     ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1543
1544     check_service_is_installed();
1545
1546     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1547
1548     delete_test_files();
1549 }
1550
1551 static void test_MsiSetComponentState(void)
1552 {
1553     INSTALLSTATE installed, action;
1554     MSIHANDLE package;
1555     char path[MAX_PATH];
1556     UINT r;
1557
1558     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1559
1560     CoInitialize(NULL);
1561
1562     lstrcpy(path, CURR_DIR);
1563     lstrcat(path, "\\");
1564     lstrcat(path, msifile);
1565
1566     r = MsiOpenPackage(path, &package);
1567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1568
1569     r = MsiDoAction(package, "CostInitialize");
1570     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1571
1572     r = MsiDoAction(package, "FileCost");
1573     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1574
1575     r = MsiDoAction(package, "CostFinalize");
1576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1577
1578     r = MsiGetComponentState(package, "dangler", &installed, &action);
1579     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1580     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1581     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1582
1583     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1585
1586     MsiCloseHandle(package);
1587     CoUninitialize();
1588
1589     DeleteFileA(msifile);
1590 }
1591
1592 static void test_packagecoltypes(void)
1593 {
1594     MSIHANDLE hdb, view, rec;
1595     char path[MAX_PATH];
1596     LPCSTR query;
1597     UINT r, count;
1598
1599     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1600
1601     CoInitialize(NULL);
1602
1603     lstrcpy(path, CURR_DIR);
1604     lstrcat(path, "\\");
1605     lstrcat(path, msifile);
1606
1607     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1609
1610     query = "SELECT * FROM `Media`";
1611     r = MsiDatabaseOpenView( hdb, query, &view );
1612     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1613
1614     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1615     count = MsiRecordGetFieldCount( rec );
1616     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1617     ok(count == 6, "Expected 6, got %d\n", count);
1618     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1619     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1620     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1621     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1622     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1623     ok(check_record(rec, 6, "Source"), "wrong column label\n");
1624     MsiCloseHandle(rec);
1625
1626     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1627     count = MsiRecordGetFieldCount( rec );
1628     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1629     ok(count == 6, "Expected 6, got %d\n", count);
1630     ok(check_record(rec, 1, "i2"), "wrong column label\n");
1631     ok(check_record(rec, 2, "i4"), "wrong column label\n");
1632     ok(check_record(rec, 3, "L64"), "wrong column label\n");
1633     ok(check_record(rec, 4, "S255"), "wrong column label\n");
1634     ok(check_record(rec, 5, "S32"), "wrong column label\n");
1635     ok(check_record(rec, 6, "S72"), "wrong column label\n");
1636
1637     MsiCloseHandle(rec);
1638     MsiCloseHandle(view);
1639     MsiCloseHandle(hdb);
1640     DeleteFile(msifile);
1641 }
1642
1643 static void create_cc_test_files(void)
1644 {
1645     CCAB cabParams;
1646     HFCI hfci;
1647     ERF erf;
1648     static CHAR cab_context[] = "test%d.cab";
1649     BOOL res;
1650
1651     create_file("maximus", 500);
1652     create_file("augustus", 50000);
1653     create_file("tiberius", 500);
1654     create_file("caesar", 500);
1655
1656     set_cab_parameters(&cabParams, "test1.cab", 40000);
1657
1658     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1659                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1660                       get_temp_file, &cabParams, cab_context);
1661     ok(hfci != NULL, "Failed to create an FCI context\n");
1662
1663     res = add_file(hfci, "maximus", tcompTYPE_NONE);
1664     ok(res, "Failed to add file maximus\n");
1665
1666     res = add_file(hfci, "augustus", tcompTYPE_NONE);
1667     ok(res, "Failed to add file augustus\n");
1668
1669     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
1670     ok(res, "Failed to add file tiberius\n");
1671
1672     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1673     ok(res, "Failed to flush the cabinet\n");
1674
1675     res = FCIDestroy(hfci);
1676     ok(res, "Failed to destroy the cabinet\n");
1677
1678     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1679
1680     DeleteFile("maximus");
1681     DeleteFile("augustus");
1682     DeleteFile("tiberius");
1683     DeleteFile("caesar");
1684 }
1685
1686 static void delete_cab_files(void)
1687 {
1688     SHFILEOPSTRUCT shfl;
1689     CHAR path[MAX_PATH+10];
1690
1691     lstrcpyA(path, CURR_DIR);
1692     lstrcatA(path, "\\*.cab");
1693     path[strlen(path) + 1] = '\0';
1694
1695     shfl.hwnd = NULL;
1696     shfl.wFunc = FO_DELETE;
1697     shfl.pFrom = path;
1698     shfl.pTo = NULL;
1699     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1700
1701     SHFileOperation(&shfl);
1702 }
1703
1704 static void test_continuouscabs(void)
1705 {
1706     UINT r;
1707
1708     create_cc_test_files();
1709     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1710
1711     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1712
1713     r = MsiInstallProductA(msifile, NULL);
1714     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1715     {
1716         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1717         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1718         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1719         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1720         ok(delete_pf("msitest", FALSE), "File not installed\n");
1721     }
1722
1723     delete_cab_files();
1724     DeleteFile(msifile);
1725
1726     create_cc_test_files();
1727     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
1728
1729     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1730
1731     r = MsiInstallProductA(msifile, NULL);
1732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1733     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1734     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
1735     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
1736     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1737     ok(delete_pf("msitest", FALSE), "File not installed\n");
1738
1739     delete_cab_files();
1740     DeleteFile(msifile);
1741 }
1742
1743 static void test_caborder(void)
1744 {
1745     UINT r;
1746
1747     create_file("imperator", 100);
1748     create_file("maximus", 500);
1749     create_file("augustus", 50000);
1750     create_file("caesar", 500);
1751
1752     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1753
1754     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1755
1756     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1757     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1758     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1759
1760     r = MsiInstallProductA(msifile, NULL);
1761     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1762     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1763     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1764     todo_wine
1765     {
1766         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1767         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1768     }
1769
1770     delete_cab_files();
1771
1772     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1773     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1774     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1775
1776     r = MsiInstallProductA(msifile, NULL);
1777     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1778     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1779     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1780     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1781     todo_wine
1782     {
1783         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1784     }
1785
1786     delete_cab_files();
1787     DeleteFile(msifile);
1788
1789     create_cc_test_files();
1790     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1791
1792     r = MsiInstallProductA(msifile, NULL);
1793     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1794     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1795     ok(!delete_pf("msitest", FALSE), "File is installed\n");
1796     todo_wine
1797     {
1798         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1799         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1800     }
1801
1802     delete_cab_files();
1803     DeleteFile(msifile);
1804
1805     create_cc_test_files();
1806     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1807
1808     r = MsiInstallProductA(msifile, NULL);
1809     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1810     todo_wine
1811     {
1812         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1813         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1814         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1815         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1816     }
1817
1818     delete_cab_files();
1819     DeleteFile("imperator");
1820     DeleteFile("maximus");
1821     DeleteFile("augustus");
1822     DeleteFile("caesar");
1823     DeleteFile(msifile);
1824 }
1825
1826 static void test_mixedmedia(void)
1827 {
1828     UINT r;
1829
1830     CreateDirectoryA("msitest", NULL);
1831     create_file("msitest\\maximus", 500);
1832     create_file("msitest\\augustus", 500);
1833     create_file("caesar", 500);
1834
1835     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1836
1837     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1838
1839     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1840
1841     r = MsiInstallProductA(msifile, NULL);
1842     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1843     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1844     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1845     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1846     ok(delete_pf("msitest", FALSE), "File not installed\n");
1847
1848     /* Delete the files in the temp (current) folder */
1849     DeleteFile("msitest\\maximus");
1850     DeleteFile("msitest\\augustus");
1851     RemoveDirectory("msitest");
1852     DeleteFile("caesar");
1853     DeleteFile("test1.cab");
1854     DeleteFile(msifile);
1855 }
1856
1857 static void test_samesequence(void)
1858 {
1859     UINT r;
1860
1861     create_cc_test_files();
1862     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1863
1864     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1865
1866     r = MsiInstallProductA(msifile, NULL);
1867     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1868     {
1869         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1870         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1871         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1872         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1873         ok(delete_pf("msitest", FALSE), "File not installed\n");
1874     }
1875
1876     delete_cab_files();
1877     DeleteFile(msifile);
1878 }
1879
1880 static void test_uiLevelFlags(void)
1881 {
1882     UINT r;
1883
1884     create_cc_test_files();
1885     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1886
1887     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1888
1889     r = MsiInstallProductA(msifile, NULL);
1890     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1891     {
1892         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1893         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1894         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1895         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1896         ok(delete_pf("msitest", FALSE), "File not installed\n");
1897     }
1898
1899     delete_cab_files();
1900     DeleteFile(msifile);
1901 }
1902
1903 static BOOL file_matches(LPSTR path)
1904 {
1905     CHAR buf[MAX_PATH];
1906     HANDLE file;
1907     DWORD size;
1908
1909     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1910                       NULL, OPEN_EXISTING, 0, NULL);
1911
1912     ZeroMemory(buf, MAX_PATH);
1913     ReadFile(file, buf, 15, &size, NULL);
1914     CloseHandle(file);
1915
1916     return !lstrcmp(buf, "msitest\\maximus");
1917 }
1918
1919 static void test_readonlyfile(void)
1920 {
1921     UINT r;
1922     DWORD size;
1923     HANDLE file;
1924     CHAR path[MAX_PATH];
1925
1926     CreateDirectoryA("msitest", NULL);
1927     create_file("msitest\\maximus", 500);
1928     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1929
1930     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1931
1932     lstrcpy(path, PROG_FILES_DIR);
1933     lstrcat(path, "\\msitest");
1934     CreateDirectory(path, NULL);
1935
1936     lstrcat(path, "\\maximus");
1937     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1938                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1939
1940     WriteFile(file, "readonlyfile", 20, &size, NULL);
1941     CloseHandle(file);
1942
1943     r = MsiInstallProductA(msifile, NULL);
1944     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1945     ok(file_matches(path), "Expected file to be overwritten\n");
1946     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1947     ok(delete_pf("msitest", FALSE), "File not installed\n");
1948
1949     /* Delete the files in the temp (current) folder */
1950     DeleteFile("msitest\\maximus");
1951     RemoveDirectory("msitest");
1952     DeleteFile(msifile);
1953 }
1954
1955 static void test_setdirproperty(void)
1956 {
1957     UINT r;
1958
1959     CreateDirectoryA("msitest", NULL);
1960     create_file("msitest\\maximus", 500);
1961     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1962
1963     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1964
1965     r = MsiInstallProductA(msifile, NULL);
1966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1967     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1968     ok(delete_cf("msitest", FALSE), "File not installed\n");
1969
1970     /* Delete the files in the temp (current) folder */
1971     DeleteFile(msifile);
1972     DeleteFile("msitest\\maximus");
1973     RemoveDirectory("msitest");
1974 }
1975
1976 static void test_cabisextracted(void)
1977 {
1978     UINT r;
1979
1980     CreateDirectoryA("msitest", NULL);
1981     create_file("msitest\\gaius", 500);
1982     create_file("maximus", 500);
1983     create_file("augustus", 500);
1984     create_file("caesar", 500);
1985
1986     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1987     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1988     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1989
1990     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
1991
1992     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1993
1994     r = MsiInstallProductA(msifile, NULL);
1995     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1996     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1997     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1998     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1999     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
2000     ok(delete_pf("msitest", FALSE), "File not installed\n");
2001
2002     /* Delete the files in the temp (current) folder */
2003     delete_cab_files();
2004     DeleteFile(msifile);
2005     DeleteFile("maximus");
2006     DeleteFile("augustus");
2007     DeleteFile("caesar");
2008     DeleteFile("msitest\\gaius");
2009     RemoveDirectory("msitest");
2010 }
2011
2012 static void test_concurrentinstall(void)
2013 {
2014     UINT r;
2015     CHAR path[MAX_PATH];
2016
2017     CreateDirectoryA("msitest", NULL);
2018     CreateDirectoryA("msitest\\msitest", NULL);
2019     create_file("msitest\\maximus", 500);
2020     create_file("msitest\\msitest\\augustus", 500);
2021
2022     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
2023
2024     lstrcpyA(path, CURR_DIR);
2025     lstrcatA(path, "\\msitest\\concurrent.msi");
2026     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
2027
2028     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2029
2030     r = MsiInstallProductA(msifile, NULL);
2031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2032     if (!delete_pf("msitest\\augustus", TRUE))
2033         trace("concurrent installs not supported\n");
2034     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2035     ok(delete_pf("msitest", FALSE), "File not installed\n");
2036
2037     DeleteFile(path);
2038
2039     r = MsiInstallProductA(msifile, NULL);
2040     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2041     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2042     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2043     ok(delete_pf("msitest", FALSE), "File not installed\n");
2044
2045     DeleteFile(msifile);
2046     DeleteFile("msitest\\msitest\\augustus");
2047     DeleteFile("msitest\\maximus");
2048     RemoveDirectory("msitest\\msitest");
2049     RemoveDirectory("msitest");
2050 }
2051
2052 static void test_setpropertyfolder(void)
2053 {
2054     UINT r;
2055     CHAR path[MAX_PATH];
2056
2057     lstrcpyA(path, PROG_FILES_DIR);
2058     lstrcatA(path, "\\msitest\\added");
2059
2060     CreateDirectoryA("msitest", NULL);
2061     create_file("msitest\\maximus", 500);
2062
2063     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
2064
2065     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2066
2067     r = MsiInstallProductA(msifile, NULL);
2068     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2069     if (GetFileAttributesA(path) == FILE_ATTRIBUTE_DIRECTORY)
2070     {
2071         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
2072         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
2073         ok(delete_pf("msitest", FALSE), "File not installed\n");
2074     }
2075     else
2076     {
2077         trace("changing folder property not supported\n");
2078         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2079         ok(delete_pf("msitest", FALSE), "File not installed\n");
2080     }
2081
2082     /* Delete the files in the temp (current) folder */
2083     DeleteFile(msifile);
2084     DeleteFile("msitest\\maximus");
2085     RemoveDirectory("msitest");
2086 }
2087
2088 static BOOL file_exists(LPCSTR file)
2089 {
2090     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
2091 }
2092
2093 static BOOL pf_exists(LPCSTR file)
2094 {
2095     CHAR path[MAX_PATH];
2096
2097     lstrcpyA(path, PROG_FILES_DIR);
2098     lstrcatA(path, "\\");
2099     lstrcatA(path, file);
2100
2101     return file_exists(path);
2102 }
2103
2104 static void delete_pfmsitest_files(void)
2105 {
2106     SHFILEOPSTRUCT shfl;
2107     CHAR path[MAX_PATH+11];
2108
2109     lstrcpyA(path, PROG_FILES_DIR);
2110     lstrcatA(path, "\\msitest\\*");
2111     path[strlen(path) + 1] = '\0';
2112
2113     shfl.hwnd = NULL;
2114     shfl.wFunc = FO_DELETE;
2115     shfl.pFrom = path;
2116     shfl.pTo = NULL;
2117     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
2118
2119     SHFileOperation(&shfl);
2120
2121     lstrcpyA(path, PROG_FILES_DIR);
2122     lstrcatA(path, "\\msitest");
2123     RemoveDirectoryA(path);
2124 }
2125
2126 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
2127 {
2128     char val[MAX_PATH];
2129     DWORD size, type;
2130     LONG res;
2131
2132     size = MAX_PATH;
2133     val[0] = '\0';
2134     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
2135
2136     if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
2137     {
2138         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2139         return;
2140     }
2141
2142     if (!expected)
2143         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
2144     else
2145     {
2146         if (bcase)
2147             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
2148         else
2149             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
2150     }
2151 }
2152
2153 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
2154 {
2155     DWORD val, size, type;
2156     LONG res;
2157
2158     size = sizeof(DWORD);
2159     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2160
2161     if (res != ERROR_SUCCESS || type != REG_DWORD)
2162     {
2163         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2164         return;
2165     }
2166
2167     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
2168 }
2169
2170 #define CHECK_REG_STR(prodkey, name, expected) \
2171     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2172
2173 #define CHECK_REG_ISTR(prodkey, name, expected) \
2174     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2175
2176 #define CHECK_REG_DWORD(prodkey, name, expected) \
2177     check_reg_dword(prodkey, name, expected, __LINE__);
2178
2179 static void get_date_str(LPSTR date)
2180 {
2181     SYSTEMTIME systime;
2182
2183     static const char date_fmt[] = "%d%02d%02d";
2184     GetLocalTime(&systime);
2185     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2186 }
2187
2188 static void test_publish_registerproduct(void)
2189 {
2190     UINT r;
2191     LONG res;
2192     HKEY uninstall, prodkey;
2193     INSTALLSTATE state;
2194     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2195     char date[MAX_PATH];
2196     char temp[MAX_PATH];
2197
2198     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2199
2200     if (!pMsiQueryComponentStateA)
2201     {
2202         skip("MsiQueryComponentStateA is not available\n");
2203         return;
2204     }
2205
2206     get_date_str(date);
2207     GetTempPath(MAX_PATH, temp);
2208
2209     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2211
2212     CreateDirectoryA("msitest", NULL);
2213     create_file("msitest\\maximus", 500);
2214
2215     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2216
2217     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2218
2219     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2220     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2221
2222     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2223     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2224
2225     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2226     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2227
2228     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2229                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2230     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2231     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2232
2233     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2234     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2235
2236     /* RegisterProduct */
2237     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2239     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2240     ok(pf_exists("msitest"), "File not installed\n");
2241
2242     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2243     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2244
2245     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2246     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2247
2248     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2249     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2250
2251     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2252                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2253     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2254     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2255
2256     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2258
2259     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2260     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2261     CHECK_REG_STR(prodkey, "InstallDate", date);
2262     CHECK_REG_STR(prodkey, "InstallSource", temp);
2263     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2264     CHECK_REG_STR(prodkey, "Publisher", "Wine");
2265     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2266     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2267     CHECK_REG_STR(prodkey, "Comments", NULL);
2268     CHECK_REG_STR(prodkey, "Contact", NULL);
2269     CHECK_REG_STR(prodkey, "HelpLink", NULL);
2270     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2271     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2272     CHECK_REG_STR(prodkey, "Readme", NULL);
2273     CHECK_REG_STR(prodkey, "Size", NULL);
2274     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2275     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2276     CHECK_REG_DWORD(prodkey, "Language", 1033);
2277     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2278     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2279     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2280     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2281     todo_wine
2282     {
2283         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2284     }
2285
2286     RegCloseKey(prodkey);
2287
2288     /* try to uninstall after RegisterProduct */
2289     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2290     todo_wine
2291     {
2292         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2293     }
2294     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2295     ok(pf_exists("msitest"), "File deleted\n");
2296
2297     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2298     todo_wine
2299     {
2300         ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2301     }
2302
2303     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2304     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2305
2306     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2307     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2308
2309     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2310                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2311     todo_wine
2312     {
2313         ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2314     }
2315     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2316
2317     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2318     todo_wine
2319     {
2320         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2321     }
2322
2323     todo_wine
2324     {
2325         CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2326         CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2327         CHECK_REG_STR(prodkey, "InstallDate", date);
2328         CHECK_REG_STR(prodkey, "InstallSource", temp);
2329         CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2330         CHECK_REG_STR(prodkey, "Publisher", "Wine");
2331         CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2332         CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2333         CHECK_REG_STR(prodkey, "Comments", NULL);
2334         CHECK_REG_STR(prodkey, "Contact", NULL);
2335         CHECK_REG_STR(prodkey, "HelpLink", NULL);
2336         CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2337         CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2338         CHECK_REG_STR(prodkey, "Readme", NULL);
2339         CHECK_REG_STR(prodkey, "Size", NULL);
2340         CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2341         CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2342         CHECK_REG_DWORD(prodkey, "Language", 1033);
2343         CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2344         CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2345         CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2346         CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2347         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2348     }
2349
2350     RegCloseKey(prodkey);
2351
2352     /* full install to remove */
2353     r = MsiInstallProductA(msifile, "FULL=1");
2354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2355     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2357
2358     RegCloseKey(uninstall);
2359     DeleteFile(msifile);
2360     DeleteFile("msitest\\maximus");
2361     RemoveDirectory("msitest");
2362     delete_pfmsitest_files();
2363 }
2364
2365 static void test_publish_publishproduct(void)
2366 {
2367     UINT r;
2368     LONG res;
2369     HKEY uninstall, prodkey;
2370     INSTALLSTATE state;
2371     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2372
2373     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2374
2375     if (!pMsiQueryComponentStateA)
2376     {
2377         skip("MsiQueryComponentStateA is not available\n");
2378         return;
2379     }
2380
2381     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2383
2384     CreateDirectoryA("msitest", NULL);
2385     create_file("msitest\\maximus", 500);
2386
2387     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2388
2389     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2390
2391     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2392     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2393
2394     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2395     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2396
2397     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2398     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2399
2400     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2401                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2402     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2403     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2404
2405     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2406     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2407
2408     /* PublishProduct */
2409     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2410     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2411     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2412     ok(pf_exists("msitest"), "File not installed\n");
2413
2414     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2415     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2416
2417     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2418     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2419
2420     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2421     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2422
2423     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2424                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2425     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2426     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2427
2428     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2429     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2430
2431     /* try to uninstall after PublishProduct */
2432     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2434     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2435     ok(pf_exists("msitest"), "File deleted\n");
2436
2437     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2438     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2439
2440     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2441     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2442
2443     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2444     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2445
2446     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2447                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2448     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2449     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2450
2451     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2452     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2453
2454     /* full install to remove */
2455     r = MsiInstallProductA(msifile, "FULL=1");
2456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2457     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2458     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2459
2460     RegCloseKey(uninstall);
2461     DeleteFile(msifile);
2462     DeleteFile("msitest\\maximus");
2463     RemoveDirectory("msitest");
2464     delete_pfmsitest_files();
2465 }
2466
2467 static void test_publish_publishfeatures(void)
2468 {
2469     UINT r;
2470     LONG res;
2471     HKEY uninstall, prodkey;
2472     INSTALLSTATE state;
2473     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2474
2475     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2476
2477     if (!pMsiQueryComponentStateA)
2478     {
2479         skip("MsiQueryComponentStateA is not available\n");
2480         return;
2481     }
2482
2483     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2485
2486     CreateDirectoryA("msitest", NULL);
2487     create_file("msitest\\maximus", 500);
2488
2489     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2490
2491     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2492
2493     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2494     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2495
2496     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2497     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2498
2499     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2500     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2501
2502     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2503                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2504     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2505     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2506
2507     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2508     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2509
2510     /* PublishFeatures */
2511     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2512     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2513     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2514     ok(pf_exists("msitest"), "File not installed\n");
2515
2516     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2517     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2518
2519     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2520     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2521
2522     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2523     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2524
2525     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2526                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2527     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2528     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2529
2530     /* try to uninstall after PublishFeatures */
2531     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2532     todo_wine
2533     {
2534         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2535     }
2536     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2537     ok(pf_exists("msitest"), "File deleted\n");
2538
2539     /* PublishFeatures and PublishProduct */
2540     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 PUBLISH_FEATURES=1");
2541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2542     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2543     ok(pf_exists("msitest"), "File not installed\n");
2544
2545     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2546     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2547
2548     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2549     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2550
2551     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2552     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2553
2554     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2555                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2556     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2557     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2558
2559     /* PublishFeatures and RegisterProduct */
2560     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_FEATURES=1");
2561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2562     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2563     ok(pf_exists("msitest"), "File not installed\n");
2564
2565     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2566     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2567
2568     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2569     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2570
2571     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2572     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2573
2574     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2575                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2576     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2577     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2578
2579     /* full install to remove */
2580     r = MsiInstallProductA(msifile, "FULL=1");
2581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2582     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2583     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2584
2585     RegCloseKey(uninstall);
2586     DeleteFile(msifile);
2587     DeleteFile("msitest\\maximus");
2588     RemoveDirectory("msitest");
2589     delete_pfmsitest_files();
2590 }
2591
2592 static void test_publish_registeruser(void)
2593 {
2594     UINT r;
2595     LONG res;
2596     HKEY uninstall, prodkey;
2597     INSTALLSTATE state;
2598     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2599
2600     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2601
2602     if (!pMsiQueryComponentStateA)
2603     {
2604         skip("MsiQueryComponentStateA is not available\n");
2605         return;
2606     }
2607
2608     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2609     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2610
2611     CreateDirectoryA("msitest", NULL);
2612     create_file("msitest\\maximus", 500);
2613
2614     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2615
2616     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2617
2618     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2619     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2620
2621     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2622     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2623
2624     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2625     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2626
2627     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2628                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2629     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2630     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2631
2632     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2633     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2634
2635     /* RegisterUser */
2636     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
2637     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2638     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2639     ok(pf_exists("msitest"), "File not installed\n");
2640
2641     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2642     todo_wine
2643     {
2644         ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2645     }
2646
2647     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2648     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2649
2650     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2651     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2652
2653     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2654                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2655     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2656     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2657
2658     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2659     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2660
2661     /* try to uninstall after RegisterUser */
2662     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2663     todo_wine
2664     {
2665         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2666     }
2667     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2668     ok(pf_exists("msitest"), "File deleted\n");
2669
2670     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2671     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2672
2673     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2674     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2675
2676     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2677     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2678
2679     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2680                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2681     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2682     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2683
2684     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2685     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2686
2687     /* full install to remove */
2688     r = MsiInstallProductA(msifile, "FULL=1");
2689     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2690     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2691     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2692
2693     RegCloseKey(uninstall);
2694     DeleteFile(msifile);
2695     DeleteFile("msitest\\maximus");
2696     RemoveDirectory("msitest");
2697     delete_pfmsitest_files();
2698 }
2699
2700 static void get_user_sid(LPSTR *usersid)
2701 {
2702     HANDLE token;
2703     BYTE buf[1024];
2704     DWORD size;
2705     PTOKEN_USER user;
2706     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
2707     static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
2708
2709     *usersid = NULL;
2710     pConvertSidToStringSidA = (void *)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
2711     if (!pConvertSidToStringSidA)
2712         return;
2713
2714     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
2715     size = sizeof(buf);
2716     GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
2717     user = (PTOKEN_USER)buf;
2718     pConvertSidToStringSidA(user->User.Sid, usersid);
2719 }
2720
2721 static void test_publish_processcomponents(void)
2722 {
2723     UINT r;
2724     LONG res;
2725     HKEY uninstall, prodkey, comp;
2726     INSTALLSTATE state;
2727     LPSTR usersid;
2728     CHAR keypath[MAX_PATH];
2729     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2730
2731     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2732
2733     if (!pMsiQueryComponentStateA)
2734     {
2735         skip("MsiQueryComponentStateA is not available\n");
2736         return;
2737     }
2738
2739     get_user_sid(&usersid);
2740     if (!usersid)
2741     {
2742         skip("ConvertSidToStringSidA is not available\n");
2743         return;
2744     }
2745
2746     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2748
2749     CreateDirectoryA("msitest", NULL);
2750     create_file("msitest\\maximus", 500);
2751
2752     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2753
2754     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2755
2756     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2757     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2758
2759     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2760     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2761
2762     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2763     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2764
2765     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2766                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2767     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2768     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2769
2770     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2771     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2772
2773     /* ProcessComponent */
2774     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
2775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2776     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2777     ok(pf_exists("msitest"), "File not installed\n");
2778
2779     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2780     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2781
2782     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2783     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2784
2785     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2786                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2787     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2788     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2789
2790     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2791     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2792
2793     /* try to uninstall after ProcessComponents */
2794     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2795     todo_wine
2796     {
2797         ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2798     }
2799     ok(pf_exists("msitest\\maximus"), "File deleted\n");
2800     ok(pf_exists("msitest"), "File deleted\n");
2801
2802     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2803     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2804
2805     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2806     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2807
2808     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2809     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2810
2811     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2812                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2813     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2814     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2815
2816     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2817     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2818
2819     /* ProcessComponent with PublishProduct */
2820     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
2821     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2822     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2823     ok(pf_exists("msitest"), "File not installed\n");
2824
2825     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2826     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2827
2828     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2829     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2830
2831     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2832     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2833
2834     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2835                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2836     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2837     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2838
2839     /* uninstall */
2840     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2841     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2842
2843     /* ProcessComponent with RegisterProduct */
2844     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PROCESS_COMPONENTS=1");
2845     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2846     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2847     ok(pf_exists("msitest"), "File not installed\n");
2848
2849     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2850     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2851
2852     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2853     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2854
2855     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2856     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2857
2858     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2859                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2860     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2861     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2862
2863     /* ProcessComponent with RegisterProduct and PublishProduct */
2864     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
2865     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2866     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2867     ok(pf_exists("msitest"), "File not installed\n");
2868
2869     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2870     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2871
2872     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2873     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2874
2875     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2876     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2877
2878     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2879                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2881     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2882
2883     /* uninstall */
2884     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2886
2887     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2888     lstrcatA(keypath, usersid);
2889     lstrcatA(keypath, "\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5");
2890
2891     /* native has trouble removing the comp key unless it's a full install */
2892     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
2893     if (res == ERROR_SUCCESS)
2894     {
2895         RegDeleteKeyA(comp, "");
2896         RegCloseKey(comp);
2897     }
2898
2899     RegCloseKey(uninstall);
2900     DeleteFile(msifile);
2901     DeleteFile("msitest\\maximus");
2902     RemoveDirectory("msitest");
2903     delete_pfmsitest_files();
2904 }
2905
2906 static void test_publish(void)
2907 {
2908     UINT r;
2909     LONG res;
2910     HKEY uninstall, prodkey;
2911     INSTALLSTATE state;
2912     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2913     char date[MAX_PATH];
2914     char temp[MAX_PATH];
2915
2916     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2917
2918     if (!pMsiQueryComponentStateA)
2919     {
2920         skip("MsiQueryComponentStateA is not available\n");
2921         return;
2922     }
2923
2924     get_date_str(date);
2925     GetTempPath(MAX_PATH, temp);
2926
2927     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2929
2930     CreateDirectoryA("msitest", NULL);
2931     create_file("msitest\\maximus", 500);
2932
2933     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2934
2935     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2936
2937     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2938     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2939
2940     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2941     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2942
2943     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2944     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2945
2946     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2947                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2948     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2949     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2950
2951     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2952     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2953
2954     /* nothing published */
2955     r = MsiInstallProductA(msifile, NULL);
2956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2957     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2958     ok(pf_exists("msitest"), "File not installed\n");
2959
2960     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2961     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2962
2963     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2964     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2965
2966     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2967     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2968
2969     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2970                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2971     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2972     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2973
2974     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2975     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2976
2977     /* PublishProduct and RegisterProduct */
2978     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
2979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2980     ok(pf_exists("msitest\\maximus"), "File not installed\n");
2981     ok(pf_exists("msitest"), "File not installed\n");
2982
2983     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2984     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2985
2986     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2987     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2988
2989     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2990     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2991
2992     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2993                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2994     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2995     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2996
2997     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2999
3000     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3001     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3002     CHECK_REG_STR(prodkey, "InstallDate", date);
3003     CHECK_REG_STR(prodkey, "InstallSource", temp);
3004     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3005     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3006     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3007     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3008     CHECK_REG_STR(prodkey, "Comments", NULL);
3009     CHECK_REG_STR(prodkey, "Contact", NULL);
3010     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3011     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3012     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3013     CHECK_REG_STR(prodkey, "Readme", NULL);
3014     CHECK_REG_STR(prodkey, "Size", NULL);
3015     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3016     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3017     CHECK_REG_DWORD(prodkey, "Language", 1033);
3018     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3019     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3020     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3021     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3022     todo_wine
3023     {
3024         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3025     }
3026
3027     RegCloseKey(prodkey);
3028
3029     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3031     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3032     ok(pf_exists("msitest"), "File deleted\n");
3033
3034     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3035     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3036
3037     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3038     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3039
3040     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3041     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3042
3043     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3044                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3045     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3046     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3047
3048     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3049     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3050
3051     /* complete install */
3052     r = MsiInstallProductA(msifile, "FULL=1");
3053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3054     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3055     ok(pf_exists("msitest"), "File not installed\n");
3056
3057     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3058     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3059
3060     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3061     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3062
3063     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3064     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3065
3066     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3067                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3068     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3069     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3070
3071     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3073
3074     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3075     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3076     CHECK_REG_STR(prodkey, "InstallDate", date);
3077     CHECK_REG_STR(prodkey, "InstallSource", temp);
3078     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3079     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3080     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3081     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3082     CHECK_REG_STR(prodkey, "Comments", NULL);
3083     CHECK_REG_STR(prodkey, "Contact", NULL);
3084     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3085     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3086     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3087     CHECK_REG_STR(prodkey, "Readme", NULL);
3088     CHECK_REG_STR(prodkey, "Size", NULL);
3089     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3090     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3091     CHECK_REG_DWORD(prodkey, "Language", 1033);
3092     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3093     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3094     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3095     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3096     todo_wine
3097     {
3098         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3099     }
3100
3101     RegCloseKey(prodkey);
3102
3103     /* no UnpublishFeatures */
3104     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3106     todo_wine
3107     {
3108         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
3109         ok(!pf_exists("msitest"), "File deleted\n");
3110     }
3111
3112     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3113     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3114
3115     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3116     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3117
3118     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3119     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3120
3121     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3122                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3123     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3124     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3125
3126     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3127     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3128
3129     /* complete install */
3130     r = MsiInstallProductA(msifile, "FULL=1");
3131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3132     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3133     ok(pf_exists("msitest"), "File not installed\n");
3134
3135     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3136     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3137
3138     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3139     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3140
3141     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3142     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3143
3144     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3145                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3146     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3147     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3148
3149     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3151
3152     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3153     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3154     CHECK_REG_STR(prodkey, "InstallDate", date);
3155     CHECK_REG_STR(prodkey, "InstallSource", temp);
3156     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3157     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3158     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3159     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3160     CHECK_REG_STR(prodkey, "Comments", NULL);
3161     CHECK_REG_STR(prodkey, "Contact", NULL);
3162     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3163     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3164     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3165     CHECK_REG_STR(prodkey, "Readme", NULL);
3166     CHECK_REG_STR(prodkey, "Size", NULL);
3167     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3168     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3169     CHECK_REG_DWORD(prodkey, "Language", 1033);
3170     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3171     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3172     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3173     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3174     todo_wine
3175     {
3176         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3177     }
3178
3179     RegCloseKey(prodkey);
3180
3181     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
3182     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
3183     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3184     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3185     ok(pf_exists("msitest"), "File deleted\n");
3186
3187     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3188     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3189
3190     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3191     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3192
3193     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3194     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3195
3196     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3197                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3198     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3199     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3200
3201     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3203
3204     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3205     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3206     CHECK_REG_STR(prodkey, "InstallDate", date);
3207     CHECK_REG_STR(prodkey, "InstallSource", temp);
3208     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3209     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3210     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3211     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3212     CHECK_REG_STR(prodkey, "Comments", NULL);
3213     CHECK_REG_STR(prodkey, "Contact", NULL);
3214     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3215     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3216     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3217     CHECK_REG_STR(prodkey, "Readme", NULL);
3218     CHECK_REG_STR(prodkey, "Size", NULL);
3219     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3220     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3221     CHECK_REG_DWORD(prodkey, "Language", 1033);
3222     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3223     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3224     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3225     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3226     todo_wine
3227     {
3228         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3229     }
3230
3231     RegCloseKey(prodkey);
3232
3233     /* complete install */
3234     r = MsiInstallProductA(msifile, "FULL=1");
3235     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3236     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3237     ok(pf_exists("msitest"), "File not installed\n");
3238
3239     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3240     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3241
3242     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3243     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3244
3245     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3246     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3247
3248     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3249                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3251     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3252
3253     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3255
3256     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3257     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3258     CHECK_REG_STR(prodkey, "InstallDate", date);
3259     CHECK_REG_STR(prodkey, "InstallSource", temp);
3260     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3261     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3262     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3263     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3264     CHECK_REG_STR(prodkey, "Comments", NULL);
3265     CHECK_REG_STR(prodkey, "Contact", NULL);
3266     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3267     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3268     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3269     CHECK_REG_STR(prodkey, "Readme", NULL);
3270     CHECK_REG_STR(prodkey, "Size", NULL);
3271     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3272     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3273     CHECK_REG_DWORD(prodkey, "Language", 1033);
3274     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3275     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3276     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3277     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3278     todo_wine
3279     {
3280         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3281     }
3282
3283     RegCloseKey(prodkey);
3284
3285     /* UnpublishFeatures, both features removed */
3286     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
3287     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3288     todo_wine
3289     {
3290         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3291         ok(!pf_exists("msitest"), "File not deleted\n");
3292     }
3293
3294     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3295     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3296
3297     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3298     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3299
3300     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3301     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3302
3303     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3304                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3305     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3306     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3307
3308     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3309     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3310
3311     /* complete install */
3312     r = MsiInstallProductA(msifile, "FULL=1");
3313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3314     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3315     ok(pf_exists("msitest"), "File not installed\n");
3316
3317     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3318     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3319
3320     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3321     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3322
3323     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3324     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3325
3326     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3327                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3329     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3330
3331     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3333
3334     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3335     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3336     CHECK_REG_STR(prodkey, "InstallDate", date);
3337     CHECK_REG_STR(prodkey, "InstallSource", temp);
3338     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3339     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3340     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3341     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3342     CHECK_REG_STR(prodkey, "Comments", NULL);
3343     CHECK_REG_STR(prodkey, "Contact", NULL);
3344     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3345     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3346     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3347     CHECK_REG_STR(prodkey, "Readme", NULL);
3348     CHECK_REG_STR(prodkey, "Size", NULL);
3349     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3350     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3351     CHECK_REG_DWORD(prodkey, "Language", 1033);
3352     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3353     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3354     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3355     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3356     todo_wine
3357     {
3358         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3359     }
3360
3361     RegCloseKey(prodkey);
3362
3363     /* complete uninstall */
3364     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3366     todo_wine
3367     {
3368         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3369         ok(!pf_exists("msitest"), "File not deleted\n");
3370     }
3371
3372     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3373     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3374
3375     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3376     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3377
3378     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3379     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3380
3381     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3382                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3383     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3384     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3385
3386     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3387     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3388
3389     /* make sure 'Program Files\msitest' is removed */
3390     delete_pfmsitest_files();
3391
3392     RegCloseKey(uninstall);
3393     DeleteFile(msifile);
3394     DeleteFile("msitest\\maximus");
3395     RemoveDirectory("msitest");
3396 }
3397
3398 static void test_publishsourcelist(void)
3399 {
3400     UINT r;
3401     DWORD size;
3402     CHAR value[MAX_PATH];
3403     CHAR path[MAX_PATH];
3404     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3405
3406     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
3407     {
3408         skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
3409         return;
3410     }
3411
3412     CreateDirectoryA("msitest", NULL);
3413     create_file("msitest\\maximus", 500);
3414
3415     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3416
3417     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3418
3419     r = MsiInstallProductA(msifile, NULL);
3420     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3421     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3422     ok(pf_exists("msitest"), "File not installed\n");
3423
3424     /* nothing published */
3425     size = 0xdeadbeef;
3426     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3427                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3428     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3429     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3430
3431     size = 0xdeadbeef;
3432     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3433                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3434     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3435     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3436
3437     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
3438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3439     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3440     ok(pf_exists("msitest"), "File not installed\n");
3441
3442     /* after RegisterProduct */
3443     size = 0xdeadbeef;
3444     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3445                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3446     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3447     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3448
3449     size = 0xdeadbeef;
3450     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3451                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3452     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3453     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3454
3455     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3457     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3458     ok(pf_exists("msitest"), "File not installed\n");
3459
3460     /* after ProcessComponents */
3461     size = 0xdeadbeef;
3462     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3463                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3464     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3465     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3466
3467     size = 0xdeadbeef;
3468     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3469                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3470     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3471     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3472
3473     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3474     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3475     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3476     ok(pf_exists("msitest"), "File not installed\n");
3477
3478     /* after PublishFeatures */
3479     size = 0xdeadbeef;
3480     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3481                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3482     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3483     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3484
3485     size = 0xdeadbeef;
3486     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3487                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3488     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3489     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3490
3491     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3493     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3494     ok(pf_exists("msitest"), "File not installed\n");
3495
3496     /* after PublishProduct */
3497     size = MAX_PATH;
3498     lstrcpyA(value, "aaa");
3499     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3500                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
3501     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3502     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
3503     ok(size == 11, "Expected 11, got %d\n", size);
3504
3505     size = MAX_PATH;
3506     lstrcpyA(value, "aaa");
3507     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3508                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3511     ok(size == 0, "Expected 0, got %d\n", size);
3512
3513     size = MAX_PATH;
3514     lstrcpyA(value, "aaa");
3515     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3516                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
3517     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3518     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3519     ok(size == 0, "Expected 0, got %d\n", size);
3520
3521     lstrcpyA(path, CURR_DIR);
3522     lstrcatA(path, "\\");
3523
3524     size = MAX_PATH;
3525     lstrcpyA(value, "aaa");
3526     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3527                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3529     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3530     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3531
3532     size = MAX_PATH;
3533     lstrcpyA(value, "aaa");
3534     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3535                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
3536     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3537     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
3538     ok(size == 1, "Expected 1, got %d\n", size);
3539
3540     size = MAX_PATH;
3541     lstrcpyA(value, "aaa");
3542     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3543                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
3544     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3545     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3546     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3547
3548     size = MAX_PATH;
3549     lstrcpyA(value, "aaa");
3550     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3551                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
3552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3553     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3554     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3555
3556     size = MAX_PATH;
3557     lstrcpyA(value, "aaa");
3558     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3559                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
3560     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3561     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3562     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3563
3564     /* complete uninstall */
3565     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3567     todo_wine
3568     {
3569         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3570         ok(!pf_exists("msitest"), "File not deleted\n");
3571     }
3572
3573     /* make sure 'Program Files\msitest' is removed */
3574     delete_pfmsitest_files();
3575
3576     DeleteFile(msifile);
3577     DeleteFile("msitest\\maximus");
3578     RemoveDirectory("msitest");
3579 }
3580
3581 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
3582 {
3583     MSIHANDLE hview = 0;
3584     UINT r;
3585
3586     r = MsiDatabaseOpenView(hdb, query, &hview);
3587     if(r != ERROR_SUCCESS)
3588         return r;
3589
3590     r = MsiViewExecute(hview, hrec);
3591     if(r == ERROR_SUCCESS)
3592         r = MsiViewClose(hview);
3593     MsiCloseHandle(hview);
3594     return r;
3595 }
3596
3597 static void set_transform_summary_info(void)
3598 {
3599     UINT r;
3600     MSIHANDLE suminfo = 0;
3601
3602     /* build summary info */
3603     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
3604     todo_wine
3605     {
3606         ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
3607     }
3608
3609     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3610     todo_wine
3611     {
3612         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3613     }
3614
3615     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3616                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3617                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3618                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
3619     todo_wine
3620     {
3621         ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
3622     }
3623
3624     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3625     todo_wine
3626     {
3627         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3628     }
3629
3630     r = MsiSummaryInfoPersist(suminfo);
3631     todo_wine
3632     {
3633         ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
3634     }
3635
3636     r = MsiCloseHandle(suminfo);
3637     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
3638 }
3639
3640 static void generate_transform(void)
3641 {
3642     MSIHANDLE hdb1, hdb2;
3643     LPCSTR query;
3644     UINT r;
3645
3646     /* start with two identical databases */
3647     CopyFile(msifile, msifile2, FALSE);
3648
3649     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
3650     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3651
3652     r = MsiDatabaseCommit(hdb1);
3653     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
3654
3655     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
3656     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3657
3658     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
3659     r = run_query(hdb1, 0, query);
3660     ok(r == ERROR_SUCCESS, "failed to add property\n");
3661
3662     /* database needs to be committed */
3663     MsiDatabaseCommit(hdb1);
3664
3665     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
3666     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
3667
3668 #if 0  /* not implemented in wine yet */
3669     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
3670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3671 #endif
3672
3673     MsiCloseHandle(hdb1);
3674     MsiCloseHandle(hdb2);
3675 }
3676
3677 /* data for generating a transform */
3678
3679 /* tables transform names - encoded as they would be in an msi database file */
3680 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3681 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3682 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3683
3684 /* data in each table */
3685 static const char data1[] = /* _StringData */
3686     "propval";  /* all the strings squashed together */
3687
3688 static const WCHAR data2[] = { /* _StringPool */
3689 /*  len, refs */
3690     0,   0,    /* string 0 ''     */
3691     4,   1,    /* string 1 'prop' */
3692     3,   1,    /* string 2 'val'  */
3693 };
3694
3695 static const WCHAR data3[] = { /* Property */
3696     0x0201, 0x0001, 0x0002,
3697 };
3698
3699 static const struct {
3700     LPCWSTR name;
3701     const void *data;
3702     DWORD size;
3703 } table_transform_data[] =
3704 {
3705     { name1, data1, sizeof data1 - 1 },
3706     { name2, data2, sizeof data2 },
3707     { name3, data3, sizeof data3 },
3708 };
3709
3710 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
3711
3712 static void generate_transform_manual(void)
3713 {
3714     IStorage *stg = NULL;
3715     IStream *stm;
3716     WCHAR name[0x20];
3717     HRESULT r;
3718     DWORD i, count;
3719     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
3720
3721     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
3722
3723     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
3724
3725     r = StgCreateDocfile(name, mode, 0, &stg);
3726     ok(r == S_OK, "failed to create storage\n");
3727     if (!stg)
3728         return;
3729
3730     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
3731     ok(r == S_OK, "failed to set storage type\n");
3732
3733     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
3734     {
3735         r = IStorage_CreateStream(stg, table_transform_data[i].name,
3736                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3737         if (FAILED(r))
3738         {
3739             ok(0, "failed to create stream %08x\n", r);
3740             continue;
3741         }
3742
3743         r = IStream_Write(stm, table_transform_data[i].data,
3744                           table_transform_data[i].size, &count);
3745         if (FAILED(r) || count != table_transform_data[i].size)
3746             ok(0, "failed to write stream\n");
3747         IStream_Release(stm);
3748     }
3749
3750     IStorage_Release(stg);
3751
3752     set_transform_summary_info();
3753 }
3754
3755 static void test_transformprop(void)
3756 {
3757     UINT r;
3758
3759     CreateDirectoryA("msitest", NULL);
3760     create_file("msitest\\augustus", 500);
3761
3762     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
3763
3764     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3765
3766     r = MsiInstallProductA(msifile, NULL);
3767     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3768     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3769     ok(!delete_pf("msitest", FALSE), "File installed\n");
3770
3771     if (0)
3772         generate_transform();
3773     else
3774         generate_transform_manual();
3775
3776     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
3777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3778     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3779     ok(delete_pf("msitest", FALSE), "File not installed\n");
3780
3781     /* Delete the files in the temp (current) folder */
3782     DeleteFile(msifile);
3783     DeleteFile(msifile2);
3784     DeleteFile(mstfile);
3785     DeleteFile("msitest\\augustus");
3786     RemoveDirectory("msitest");
3787 }
3788
3789 static void test_currentworkingdir(void)
3790 {
3791     UINT r;
3792     CHAR path[MAX_PATH];
3793     LPSTR ptr, ptr2;
3794
3795     CreateDirectoryA("msitest", NULL);
3796     create_file("msitest\\augustus", 500);
3797
3798     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
3799
3800     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3801
3802     CreateDirectoryA("diffdir", NULL);
3803     SetCurrentDirectoryA("diffdir");
3804
3805     sprintf(path, "..\\%s", msifile);
3806     r = MsiInstallProductA(path, NULL);
3807     todo_wine
3808     {
3809         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
3810         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3811         ok(!delete_pf("msitest", FALSE), "File installed\n");
3812     }
3813
3814     sprintf(path, "%s\\%s", CURR_DIR, msifile);
3815     r = MsiInstallProductA(path, NULL);
3816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3817     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3818     ok(delete_pf("msitest", FALSE), "File not installed\n");
3819
3820     lstrcpyA(path, CURR_DIR);
3821     if (path[lstrlenA(path) - 1] != '\\')
3822         lstrcatA(path, "\\");
3823     lstrcatA(path, "msitest.msi");
3824
3825     ptr2 = strrchr(path, '\\');
3826     *ptr2 = '\0';
3827     ptr = strrchr(path, '\\');
3828     *ptr2 = '\\';
3829     *(ptr++) = '\0';
3830
3831     SetCurrentDirectoryA(path);
3832
3833     r = MsiInstallProductA(ptr, NULL);
3834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3835     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3836     ok(delete_pf("msitest", FALSE), "File not installed\n");
3837
3838     SetCurrentDirectoryA(CURR_DIR);
3839
3840     DeleteFile(msifile);
3841     DeleteFile("msitest\\augustus");
3842     RemoveDirectory("msitest");
3843     RemoveDirectory("diffdir");
3844 }
3845
3846 static void set_admin_summary_info(const CHAR *name)
3847 {
3848     MSIHANDLE db, summary;
3849     UINT r;
3850
3851     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
3852     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3853
3854     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
3855     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3856
3857     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
3858     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3859
3860     /* write the summary changes back to the stream */
3861     r = MsiSummaryInfoPersist(summary);
3862     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3863
3864     MsiCloseHandle(summary);
3865
3866     r = MsiDatabaseCommit(db);
3867     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3868
3869     MsiCloseHandle(db);
3870 }
3871
3872 static void test_admin(void)
3873 {
3874     UINT r;
3875
3876     CreateDirectoryA("msitest", NULL);
3877     create_file("msitest\\augustus", 500);
3878
3879     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
3880     set_admin_summary_info(msifile);
3881
3882     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3883
3884     r = MsiInstallProductA(msifile, NULL);
3885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3886     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3887     ok(!delete_pf("msitest", FALSE), "File installed\n");
3888     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
3889     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
3890
3891     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
3892     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3893     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3894     ok(!delete_pf("msitest", FALSE), "File installed\n");
3895     todo_wine
3896     {
3897         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
3898         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
3899     }
3900
3901     DeleteFile(msifile);
3902     DeleteFile("msitest\\augustus");
3903     RemoveDirectory("msitest");
3904 }
3905
3906 static void set_admin_property_stream(LPCSTR file)
3907 {
3908     IStorage *stg;
3909     IStream *stm;
3910     WCHAR fileW[MAX_PATH];
3911     HRESULT hr;
3912     DWORD count;
3913     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
3914
3915     /* AdminProperties */
3916     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
3917     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
3918
3919     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
3920
3921     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
3922     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3923     if (!stg)
3924         return;
3925
3926     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3927     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3928
3929     hr = IStream_Write(stm, data, sizeof(data), &count);
3930     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
3931
3932     IStream_Release(stm);
3933     IStorage_Release(stg);
3934 }
3935
3936 static void test_adminprops(void)
3937 {
3938     UINT r;
3939
3940     CreateDirectoryA("msitest", NULL);
3941     create_file("msitest\\augustus", 500);
3942
3943     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
3944     set_admin_summary_info(msifile);
3945     set_admin_property_stream(msifile);
3946
3947     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3948
3949     r = MsiInstallProductA(msifile, NULL);
3950     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3951     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
3952     ok(delete_pf("msitest", FALSE), "File installed\n");
3953
3954     DeleteFile(msifile);
3955     DeleteFile("msitest\\augustus");
3956     RemoveDirectory("msitest");
3957 }
3958
3959 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
3960 {
3961     CHAR path[MAX_PATH];
3962
3963     lstrcpyA(path, PROG_FILES_DIR);
3964     lstrcatA(path, "\\");
3965     lstrcatA(path, file);
3966
3967     if (is_file)
3968         create_file_data(path, data, 500);
3969     else
3970         CreateDirectoryA(path, NULL);
3971 }
3972
3973 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
3974
3975 static void test_removefiles(void)
3976 {
3977     UINT r;
3978
3979     CreateDirectoryA("msitest", NULL);
3980     create_file("msitest\\hydrogen", 500);
3981     create_file("msitest\\helium", 500);
3982     create_file("msitest\\lithium", 500);
3983
3984     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
3985
3986     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3987
3988     r = MsiInstallProductA(msifile, NULL);
3989     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3990     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
3991     ok(!pf_exists("msitest\\helium"), "File installed\n");
3992     ok(pf_exists("msitest\\lithium"), "File not installed\n");
3993     ok(pf_exists("msitest"), "File not installed\n");
3994
3995     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3996     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3997     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
3998     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
3999     todo_wine
4000     {
4001         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4002         ok(delete_pf("msitest", FALSE), "File deleted\n");
4003     }
4004
4005     create_pf("msitest", FALSE);
4006     create_pf("msitest\\hydrogen", TRUE);
4007     create_pf("msitest\\helium", TRUE);
4008     create_pf("msitest\\lithium", TRUE);
4009
4010     r = MsiInstallProductA(msifile, NULL);
4011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4012     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4013     ok(pf_exists("msitest\\helium"), "File not installed\n");
4014     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4015     ok(pf_exists("msitest"), "File not installed\n");
4016
4017     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4019     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4020     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4021     todo_wine
4022     {
4023         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4024         ok(delete_pf("msitest", FALSE), "File deleted\n");
4025     }
4026
4027     create_pf("msitest", FALSE);
4028     create_pf("msitest\\furlong", TRUE);
4029     create_pf("msitest\\firkin", TRUE);
4030     create_pf("msitest\\fortnight", TRUE);
4031     create_pf("msitest\\becquerel", TRUE);
4032     create_pf("msitest\\dioptre", TRUE);
4033     create_pf("msitest\\attoparsec", TRUE);
4034     create_pf("msitest\\storeys", TRUE);
4035     create_pf("msitest\\block", TRUE);
4036     create_pf("msitest\\siriometer", TRUE);
4037
4038     r = MsiInstallProductA(msifile, NULL);
4039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4040     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4041     ok(!pf_exists("msitest\\helium"), "File installed\n");
4042     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4043     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4044     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4045     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4046     ok(pf_exists("msitest"), "File not installed\n");
4047     todo_wine
4048     {
4049         ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4050         ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4051         ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4052         ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4053         ok(!pf_exists("msitest\\block"), "File not deleted\n");
4054         ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4055     }
4056
4057     create_pf("msitest\\furlong", TRUE);
4058     create_pf("msitest\\firkin", TRUE);
4059     create_pf("msitest\\fortnight", TRUE);
4060     create_pf("msitest\\storeys", TRUE);
4061     create_pf("msitest\\block", TRUE);
4062     create_pf("msitest\\siriometer", TRUE);
4063
4064     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4066     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4067     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4068     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4069     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4070     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4071     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4072     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4073     todo_wine
4074     {
4075         ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4076         ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4077         ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4078         ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4079         ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4080     }
4081     ok(delete_pf("msitest", FALSE), "File deleted\n");
4082
4083     DeleteFile(msifile);
4084     DeleteFile("msitest\\hydrogen");
4085     DeleteFile("msitest\\helium");
4086     DeleteFile("msitest\\lithium");
4087     RemoveDirectory("msitest");
4088 }
4089
4090 static void test_movefiles(void)
4091 {
4092     UINT r;
4093     char props[MAX_PATH];
4094
4095     CreateDirectoryA("msitest", NULL);
4096     create_file("msitest\\augustus", 100);
4097     create_file("cameroon", 100);
4098     create_file("djibouti", 100);
4099     create_file("egypt", 100);
4100     create_file("finland", 100);
4101     create_file("gambai", 100);
4102     create_file("honduras", 100);
4103     create_file("msitest\\india", 100);
4104     create_file("japan", 100);
4105     create_file("kenya", 100);
4106     CreateDirectoryA("latvia", NULL);
4107     create_file("nauru", 100);
4108     create_file("apple", 100);
4109     create_file("application", 100);
4110     create_file("ape", 100);
4111     create_file("foo", 100);
4112     create_file("fao", 100);
4113     create_file("fbod", 100);
4114     create_file("budding", 100);
4115     create_file("buddy", 100);
4116     create_file("bud", 100);
4117     create_file("bar", 100);
4118     create_file("bur", 100);
4119     create_file("bird", 100);
4120
4121     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4122
4123     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4124
4125     /* if the source or dest property is not a full path,
4126      * windows tries to access it as a network resource
4127      */
4128
4129     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4130             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4131             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4132
4133     r = MsiInstallProductA(msifile, props);
4134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4135     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4136     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4137     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4138     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4139     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4140     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4141     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4142     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4143     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4144     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4145     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4146     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4147     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4148     /* either apple or application will be moved depending on directory order */
4149     if (!delete_pf("msitest\\apple", TRUE))
4150         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4151     else
4152         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4153     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4154     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4155     /* either fao or foo will be moved depending on directory order */
4156     if (delete_pf("msitest\\foo", TRUE))
4157         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4158     else
4159         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4160     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4161     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4162     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4163     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4164     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4165     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4166     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4167     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4168     ok(delete_pf("msitest", FALSE), "File not installed\n");
4169     ok(DeleteFileA("cameroon"), "File moved\n");
4170     ok(!DeleteFileA("djibouti"), "File not moved\n");
4171     ok(DeleteFileA("egypt"), "File moved\n");
4172     ok(DeleteFileA("finland"), "File moved\n");
4173     ok(DeleteFileA("gambai"), "File moved\n");
4174     ok(!DeleteFileA("honduras"), "File not moved\n");
4175     ok(DeleteFileA("msitest\\india"), "File moved\n");
4176     ok(DeleteFileA("japan"), "File moved\n");
4177     ok(!DeleteFileA("kenya"), "File not moved\n");
4178     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4179     ok(!DeleteFileA("nauru"), "File not moved\n");
4180     ok(!DeleteFileA("apple"), "File not moved\n");
4181     ok(!DeleteFileA("application"), "File not moved\n");
4182     ok(DeleteFileA("ape"), "File moved\n");
4183     ok(!DeleteFileA("foo"), "File not moved\n");
4184     ok(!DeleteFileA("fao"), "File not moved\n");
4185     ok(DeleteFileA("fbod"), "File moved\n");
4186     ok(!DeleteFileA("budding"), "File not moved\n");
4187     ok(!DeleteFileA("buddy"), "File not moved\n");
4188     ok(DeleteFileA("bud"), "File moved\n");
4189     ok(!DeleteFileA("bar"), "File not moved\n");
4190     ok(!DeleteFileA("bur"), "File not moved\n");
4191     ok(DeleteFileA("bird"), "File moved\n");
4192
4193     DeleteFile("msitest\\augustus");
4194     RemoveDirectory("msitest");
4195     DeleteFile(msifile);
4196 }
4197
4198 static void test_missingcab(void)
4199 {
4200     UINT r;
4201
4202     CreateDirectoryA("msitest", NULL);
4203     create_file("msitest\\augustus", 500);
4204     create_file("maximus", 500);
4205
4206     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
4207
4208     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4209
4210     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4211
4212     create_pf("msitest", FALSE);
4213     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4214
4215     r = MsiInstallProductA(msifile, NULL);
4216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4217     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4218     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4219     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4220     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
4221     ok(delete_pf("msitest", FALSE), "File not installed\n");
4222
4223     create_pf("msitest", FALSE);
4224     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4225     create_pf("msitest\\gaius", TRUE);
4226
4227     r = MsiInstallProductA(msifile, "GAIUS=1");
4228     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4229     todo_wine
4230     {
4231         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
4232         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4233     }
4234     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
4235     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
4236     ok(delete_pf("msitest", FALSE), "File not installed\n");
4237
4238     DeleteFile("msitest\\augustus");
4239     RemoveDirectory("msitest");
4240     DeleteFile("maximus");
4241     DeleteFile("test1.cab");
4242     DeleteFile(msifile);
4243 }
4244
4245 static void test_duplicatefiles(void)
4246 {
4247     UINT r;
4248
4249     CreateDirectoryA("msitest", NULL);
4250     create_file("msitest\\maximus", 500);
4251     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4252
4253     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4254
4255     /* fails if the destination folder is not a valid property */
4256
4257     r = MsiInstallProductA(msifile, NULL);
4258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4259     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4260     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4261     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4262     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
4263     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
4264     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
4265     ok(delete_pf("msitest", FALSE), "File not installed\n");
4266
4267     DeleteFile("msitest\\maximus");
4268     RemoveDirectory("msitest");
4269     DeleteFile(msifile);
4270 }
4271
4272 static void test_writeregistryvalues(void)
4273 {
4274     UINT r;
4275     LONG res;
4276     HKEY hkey;
4277     DWORD type, size;
4278     CHAR path[MAX_PATH];
4279
4280     CreateDirectoryA("msitest", NULL);
4281     create_file("msitest\\augustus", 500);
4282
4283     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4284
4285     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4286
4287     r = MsiInstallProductA(msifile, NULL);
4288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4289     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4290     ok(delete_pf("msitest", FALSE), "File installed\n");
4291
4292     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
4293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4294
4295     size = MAX_PATH;
4296     type = REG_MULTI_SZ;
4297     memset(path, 'a', MAX_PATH);
4298     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4300     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4301     ok(size == 15, "Expected 15, got %d\n", size);
4302     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4303
4304     DeleteFile(msifile);
4305     DeleteFile("msitest\\augustus");
4306     RemoveDirectory("msitest");
4307 }
4308
4309 static void test_sourcefolder(void)
4310 {
4311     UINT r;
4312
4313     CreateDirectoryA("msitest", NULL);
4314     create_file("augustus", 500);
4315
4316     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
4317
4318     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4319
4320     r = MsiInstallProductA(msifile, NULL);
4321     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4322     todo_wine
4323     {
4324         ok(r == ERROR_INSTALL_FAILURE,
4325            "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4326         ok(!delete_pf("msitest", FALSE), "File installed\n");
4327     }
4328
4329     RemoveDirectoryA("msitest");
4330
4331     r = MsiInstallProductA(msifile, NULL);
4332     todo_wine
4333     {
4334         ok(r == ERROR_INSTALL_FAILURE,
4335            "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4336         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4337         ok(!delete_pf("msitest", FALSE), "File installed\n");
4338     }
4339
4340     DeleteFile(msifile);
4341     DeleteFile("augustus");
4342 }
4343
4344 static void test_customaction51(void)
4345 {
4346     UINT r;
4347
4348     CreateDirectoryA("msitest", NULL);
4349     create_file("msitest\\augustus", 500);
4350
4351     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
4352
4353     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4354
4355     r = MsiInstallProductA(msifile, NULL);
4356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4357     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4358     ok(delete_pf("msitest", FALSE), "File installed\n");
4359
4360     DeleteFile(msifile);
4361     DeleteFile("msitest\\augustus");
4362     RemoveDirectory("msitest");
4363 }
4364
4365 static void test_installstate(void)
4366 {
4367     UINT r;
4368
4369     CreateDirectoryA("msitest", NULL);
4370     create_file("msitest\\alpha", 500);
4371     create_file("msitest\\beta", 500);
4372     create_file("msitest\\gamma", 500);
4373     create_file("msitest\\theta", 500);
4374     create_file("msitest\\delta", 500);
4375     create_file("msitest\\epsilon", 500);
4376     create_file("msitest\\zeta", 500);
4377     create_file("msitest\\iota", 500);
4378     create_file("msitest\\eta", 500);
4379     create_file("msitest\\kappa", 500);
4380     create_file("msitest\\lambda", 500);
4381     create_file("msitest\\mu", 500);
4382
4383     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
4384
4385     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4386
4387     r = MsiInstallProductA(msifile, NULL);
4388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4389     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4390     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4391     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4392     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4393     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4394     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4395     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4396     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4397     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4398     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4399     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4400     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4401     ok(delete_pf("msitest", FALSE), "File not installed\n");
4402
4403     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
4404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4405     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4406     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4407     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4408     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4409     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4410     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
4411     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4412     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4413     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
4414     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4415     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4416     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4417     ok(delete_pf("msitest", FALSE), "File not installed\n");
4418
4419     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
4420     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4421     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4422     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4423     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4424     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4425     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4426     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4427     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4428     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4429     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4430     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4431     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4432     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4433     ok(delete_pf("msitest", FALSE), "File not installed\n");
4434
4435     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
4436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4437     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
4438     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4439     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4440     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
4441     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4442     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4443     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4444     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4445     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4446     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4447     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4448     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4449     ok(!delete_pf("msitest", FALSE), "File installed\n");
4450
4451     DeleteFile(msifile);
4452     DeleteFile("msitest\\alpha");
4453     DeleteFile("msitest\\beta");
4454     DeleteFile("msitest\\gamma");
4455     DeleteFile("msitest\\theta");
4456     DeleteFile("msitest\\delta");
4457     DeleteFile("msitest\\epsilon");
4458     DeleteFile("msitest\\zeta");
4459     DeleteFile("msitest\\iota");
4460     DeleteFile("msitest\\eta");
4461     DeleteFile("msitest\\kappa");
4462     DeleteFile("msitest\\lambda");
4463     DeleteFile("msitest\\mu");
4464     RemoveDirectory("msitest");
4465 }
4466
4467 START_TEST(install)
4468 {
4469     DWORD len;
4470     char temp_path[MAX_PATH], prev_path[MAX_PATH];
4471
4472     init_functionpointers();
4473
4474     GetCurrentDirectoryA(MAX_PATH, prev_path);
4475     GetTempPath(MAX_PATH, temp_path);
4476     SetCurrentDirectoryA(temp_path);
4477
4478     lstrcpyA(CURR_DIR, temp_path);
4479     len = lstrlenA(CURR_DIR);
4480
4481     if(len && (CURR_DIR[len - 1] == '\\'))
4482         CURR_DIR[len - 1] = 0;
4483
4484     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
4485
4486     test_MsiInstallProduct();
4487     test_MsiSetComponentState();
4488     test_packagecoltypes();
4489     test_continuouscabs();
4490     test_caborder();
4491     test_mixedmedia();
4492     test_samesequence();
4493     test_uiLevelFlags();
4494     test_readonlyfile();
4495     test_setdirproperty();
4496     test_cabisextracted();
4497     test_concurrentinstall();
4498     test_setpropertyfolder();
4499     test_publish_registerproduct();
4500     test_publish_publishproduct();
4501     test_publish_publishfeatures();
4502     test_publish_registeruser();
4503     test_publish_processcomponents();
4504     test_publish();
4505     test_publishsourcelist();
4506     test_transformprop();
4507     test_currentworkingdir();
4508     test_admin();
4509     test_adminprops();
4510     test_removefiles();
4511     test_movefiles();
4512     test_missingcab();
4513     test_duplicatefiles();
4514     test_writeregistryvalues();
4515     test_sourcefolder();
4516     test_customaction51();
4517     test_installstate();
4518
4519     SetCurrentDirectoryA(prev_path);
4520 }