msi: msidbFileAttributesVital has no effect on the installation of files.
[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 void get_user_sid(LPSTR *usersid)
1171 {
1172     HANDLE token;
1173     BYTE buf[1024];
1174     DWORD size;
1175     PTOKEN_USER user;
1176     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
1177     static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
1178
1179     *usersid = NULL;
1180     pConvertSidToStringSidA = (void *)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
1181     if (!pConvertSidToStringSidA)
1182         return;
1183
1184     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1185     size = sizeof(buf);
1186     GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
1187     user = (PTOKEN_USER)buf;
1188     pConvertSidToStringSidA(user->User.Sid, usersid);
1189 }
1190
1191 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
1192 {
1193     CHAR buffer[0x20];
1194     UINT r;
1195     DWORD sz;
1196
1197     sz = sizeof buffer;
1198     r = MsiRecordGetString(rec, field, buffer, &sz);
1199     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1200 }
1201
1202 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
1203 {
1204     LPSTR tempname;
1205
1206     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
1207     GetTempFileNameA(".", "xx", 0, tempname);
1208
1209     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
1210     {
1211         lstrcpyA(pszTempName, tempname);
1212         HeapFree(GetProcessHeap(), 0, tempname);
1213         return TRUE;
1214     }
1215
1216     HeapFree(GetProcessHeap(), 0, tempname);
1217
1218     return FALSE;
1219 }
1220
1221 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
1222                              USHORT *pattribs, int *err, void *pv)
1223 {
1224     BY_HANDLE_FILE_INFORMATION finfo;
1225     FILETIME filetime;
1226     HANDLE handle;
1227     DWORD attrs;
1228     BOOL res;
1229
1230     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
1231                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1232
1233     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
1234
1235     res = GetFileInformationByHandle(handle, &finfo);
1236     ok(res, "Expected GetFileInformationByHandle to succeed\n");
1237    
1238     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
1239     FileTimeToDosDateTime(&filetime, pdate, ptime);
1240
1241     attrs = GetFileAttributes(pszName);
1242     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
1243
1244     return (INT_PTR)handle;
1245 }
1246
1247 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
1248 {
1249     char path[MAX_PATH];
1250     char filename[MAX_PATH];
1251
1252     lstrcpyA(path, CURR_DIR);
1253     lstrcatA(path, "\\");
1254     lstrcatA(path, file);
1255
1256     lstrcpyA(filename, file);
1257
1258     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
1259                       progress, get_open_info, compress);
1260 }
1261
1262 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
1263 {
1264     ZeroMemory(pCabParams, sizeof(CCAB));
1265
1266     pCabParams->cb = max_size;
1267     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
1268     pCabParams->setID = 0xbeef;
1269     pCabParams->iCab = 1;
1270     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
1271     lstrcatA(pCabParams->szCabPath, "\\");
1272     lstrcpyA(pCabParams->szCab, name);
1273 }
1274
1275 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
1276 {
1277     CCAB cabParams;
1278     LPCSTR ptr;
1279     HFCI hfci;
1280     ERF erf;
1281     BOOL res;
1282
1283     set_cab_parameters(&cabParams, name, max_size);
1284
1285     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1286                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1287                       get_temp_file, &cabParams, NULL);
1288
1289     ok(hfci != NULL, "Failed to create an FCI context\n");
1290
1291     ptr = files;
1292     while (*ptr)
1293     {
1294         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
1295         ok(res, "Failed to add file: %s\n", ptr);
1296         ptr += lstrlen(ptr) + 1;
1297     }
1298
1299     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1300     ok(res, "Failed to flush the cabinet\n");
1301
1302     res = FCIDestroy(hfci);
1303     ok(res, "Failed to destroy the cabinet\n");
1304 }
1305
1306 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1307 {
1308     HKEY hkey;
1309     DWORD type, size;
1310
1311     if (RegOpenKey(HKEY_LOCAL_MACHINE,
1312                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1313         return FALSE;
1314
1315     size = MAX_PATH;
1316     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1317         RegCloseKey(hkey);
1318         return FALSE;
1319     }
1320
1321     size = MAX_PATH;
1322     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1323         RegCloseKey(hkey);
1324         return FALSE;
1325     }
1326
1327     RegCloseKey(hkey);
1328     return TRUE;
1329 }
1330
1331 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1332 {
1333     HANDLE file;
1334     DWORD written;
1335
1336     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1337     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1338     WriteFile(file, data, strlen(data), &written, NULL);
1339
1340     if (size)
1341     {
1342         SetFilePointer(file, size, NULL, FILE_BEGIN);
1343         SetEndOfFile(file);
1344     }
1345
1346     CloseHandle(file);
1347 }
1348
1349 #define create_file(name, size) create_file_data(name, name, size)
1350
1351 static void create_test_files(void)
1352 {
1353     CreateDirectoryA("msitest", NULL);
1354     create_file("msitest\\one.txt", 100);
1355     CreateDirectoryA("msitest\\first", NULL);
1356     create_file("msitest\\first\\two.txt", 100);
1357     CreateDirectoryA("msitest\\second", NULL);
1358     create_file("msitest\\second\\three.txt", 100);
1359
1360     create_file("four.txt", 100);
1361     create_file("five.txt", 100);
1362     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1363
1364     create_file("msitest\\filename", 100);
1365     create_file("msitest\\service.exe", 100);
1366
1367     DeleteFileA("four.txt");
1368     DeleteFileA("five.txt");
1369 }
1370
1371 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1372 {
1373     CHAR path[MAX_PATH];
1374
1375     lstrcpyA(path, PROG_FILES_DIR);
1376     lstrcatA(path, "\\");
1377     lstrcatA(path, rel_path);
1378
1379     if (is_file)
1380         return DeleteFileA(path);
1381     else
1382         return RemoveDirectoryA(path);
1383 }
1384
1385 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1386 {
1387     CHAR path[MAX_PATH];
1388
1389     lstrcpyA(path, COMMON_FILES_DIR);
1390     lstrcatA(path, "\\");
1391     lstrcatA(path, rel_path);
1392
1393     if (is_file)
1394         return DeleteFileA(path);
1395     else
1396         return RemoveDirectoryA(path);
1397 }
1398
1399 static void delete_test_files(void)
1400 {
1401     DeleteFileA("msitest.msi");
1402     DeleteFileA("msitest.cab");
1403     DeleteFileA("msitest\\second\\three.txt");
1404     DeleteFileA("msitest\\first\\two.txt");
1405     DeleteFileA("msitest\\one.txt");
1406     DeleteFileA("msitest\\service.exe");
1407     DeleteFileA("msitest\\filename");
1408     RemoveDirectoryA("msitest\\second");
1409     RemoveDirectoryA("msitest\\first");
1410     RemoveDirectoryA("msitest");
1411 }
1412
1413 static void write_file(const CHAR *filename, const char *data, int data_size)
1414 {
1415     DWORD size;
1416
1417     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1418                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1419
1420     WriteFile(hf, data, data_size, &size, NULL);
1421     CloseHandle(hf);
1422 }
1423
1424 static void write_msi_summary_info(MSIHANDLE db)
1425 {
1426     MSIHANDLE summary;
1427     UINT r;
1428
1429     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1431
1432     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1434
1435     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1436                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1438
1439     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1441
1442     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1444
1445     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1447
1448     /* write the summary changes back to the stream */
1449     r = MsiSummaryInfoPersist(summary);
1450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1451
1452     MsiCloseHandle(summary);
1453 }
1454
1455 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1456 {
1457     MSIHANDLE db;
1458     UINT r;
1459     int j;
1460
1461     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1463
1464     /* import the tables into the database */
1465     for (j = 0; j < num_tables; j++)
1466     {
1467         const msi_table *table = &tables[j];
1468
1469         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1470
1471         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1472         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1473
1474         DeleteFileA(table->filename);
1475     }
1476
1477     write_msi_summary_info(db);
1478
1479     r = MsiDatabaseCommit(db);
1480     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1481
1482     MsiCloseHandle(db);
1483 }
1484
1485 static void check_service_is_installed(void)
1486 {
1487     SC_HANDLE scm, service;
1488     BOOL res;
1489
1490     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1491     ok(scm != NULL, "Failed to open the SC Manager\n");
1492
1493     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1494     ok(service != NULL, "Failed to open TestService\n");
1495
1496     res = DeleteService(service);
1497     ok(res, "Failed to delete TestService\n");
1498
1499     CloseServiceHandle(service);
1500     CloseServiceHandle(scm);
1501 }
1502
1503 static void test_MsiInstallProduct(void)
1504 {
1505     UINT r;
1506     CHAR path[MAX_PATH];
1507     LONG res;
1508     HKEY hkey;
1509     DWORD num, size, type;
1510     SC_HANDLE scm;
1511
1512     scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
1513     if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1514     {
1515         skip("Services are not implemented, we are most likely on win9x\n");
1516         return;
1517     }
1518     CloseServiceHandle(scm);
1519
1520     create_test_files();
1521     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1522
1523     r = MsiInstallProductA(msifile, NULL);
1524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1525
1526     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1527     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1528     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1529     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1530     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1531     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1532     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1533     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1534     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1535     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1536     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1537     ok(delete_pf("msitest", FALSE), "File not installed\n");
1538
1539     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1541
1542     size = MAX_PATH;
1543     type = REG_SZ;
1544     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1546     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1547
1548     size = MAX_PATH;
1549     type = REG_SZ;
1550     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1551     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1552
1553     size = sizeof(num);
1554     type = REG_DWORD;
1555     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1557     ok(num == 314, "Expected 314, got %d\n", num);
1558
1559     size = MAX_PATH;
1560     type = REG_SZ;
1561     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1563     ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1564
1565     check_service_is_installed();
1566
1567     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1568
1569     delete_test_files();
1570 }
1571
1572 static void test_MsiSetComponentState(void)
1573 {
1574     INSTALLSTATE installed, action;
1575     MSIHANDLE package;
1576     char path[MAX_PATH];
1577     UINT r;
1578
1579     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1580
1581     CoInitialize(NULL);
1582
1583     lstrcpy(path, CURR_DIR);
1584     lstrcat(path, "\\");
1585     lstrcat(path, msifile);
1586
1587     r = MsiOpenPackage(path, &package);
1588     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1589
1590     r = MsiDoAction(package, "CostInitialize");
1591     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1592
1593     r = MsiDoAction(package, "FileCost");
1594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1595
1596     r = MsiDoAction(package, "CostFinalize");
1597     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1598
1599     r = MsiGetComponentState(package, "dangler", &installed, &action);
1600     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1601     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1602     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1603
1604     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1606
1607     MsiCloseHandle(package);
1608     CoUninitialize();
1609
1610     DeleteFileA(msifile);
1611 }
1612
1613 static void test_packagecoltypes(void)
1614 {
1615     MSIHANDLE hdb, view, rec;
1616     char path[MAX_PATH];
1617     LPCSTR query;
1618     UINT r, count;
1619
1620     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1621
1622     CoInitialize(NULL);
1623
1624     lstrcpy(path, CURR_DIR);
1625     lstrcat(path, "\\");
1626     lstrcat(path, msifile);
1627
1628     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1629     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1630
1631     query = "SELECT * FROM `Media`";
1632     r = MsiDatabaseOpenView( hdb, query, &view );
1633     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1634
1635     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1636     count = MsiRecordGetFieldCount( rec );
1637     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1638     ok(count == 6, "Expected 6, got %d\n", count);
1639     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1640     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1641     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1642     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1643     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1644     ok(check_record(rec, 6, "Source"), "wrong column label\n");
1645     MsiCloseHandle(rec);
1646
1647     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1648     count = MsiRecordGetFieldCount( rec );
1649     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1650     ok(count == 6, "Expected 6, got %d\n", count);
1651     ok(check_record(rec, 1, "i2"), "wrong column label\n");
1652     ok(check_record(rec, 2, "i4"), "wrong column label\n");
1653     ok(check_record(rec, 3, "L64"), "wrong column label\n");
1654     ok(check_record(rec, 4, "S255"), "wrong column label\n");
1655     ok(check_record(rec, 5, "S32"), "wrong column label\n");
1656     ok(check_record(rec, 6, "S72"), "wrong column label\n");
1657
1658     MsiCloseHandle(rec);
1659     MsiCloseHandle(view);
1660     MsiCloseHandle(hdb);
1661     DeleteFile(msifile);
1662 }
1663
1664 static void create_cc_test_files(void)
1665 {
1666     CCAB cabParams;
1667     HFCI hfci;
1668     ERF erf;
1669     static CHAR cab_context[] = "test%d.cab";
1670     BOOL res;
1671
1672     create_file("maximus", 500);
1673     create_file("augustus", 50000);
1674     create_file("tiberius", 500);
1675     create_file("caesar", 500);
1676
1677     set_cab_parameters(&cabParams, "test1.cab", 40000);
1678
1679     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1680                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1681                       get_temp_file, &cabParams, cab_context);
1682     ok(hfci != NULL, "Failed to create an FCI context\n");
1683
1684     res = add_file(hfci, "maximus", tcompTYPE_NONE);
1685     ok(res, "Failed to add file maximus\n");
1686
1687     res = add_file(hfci, "augustus", tcompTYPE_NONE);
1688     ok(res, "Failed to add file augustus\n");
1689
1690     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
1691     ok(res, "Failed to add file tiberius\n");
1692
1693     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1694     ok(res, "Failed to flush the cabinet\n");
1695
1696     res = FCIDestroy(hfci);
1697     ok(res, "Failed to destroy the cabinet\n");
1698
1699     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1700
1701     DeleteFile("maximus");
1702     DeleteFile("augustus");
1703     DeleteFile("tiberius");
1704     DeleteFile("caesar");
1705 }
1706
1707 static void delete_cab_files(void)
1708 {
1709     SHFILEOPSTRUCT shfl;
1710     CHAR path[MAX_PATH+10];
1711
1712     lstrcpyA(path, CURR_DIR);
1713     lstrcatA(path, "\\*.cab");
1714     path[strlen(path) + 1] = '\0';
1715
1716     shfl.hwnd = NULL;
1717     shfl.wFunc = FO_DELETE;
1718     shfl.pFrom = path;
1719     shfl.pTo = NULL;
1720     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1721
1722     SHFileOperation(&shfl);
1723 }
1724
1725 static void test_continuouscabs(void)
1726 {
1727     UINT r;
1728
1729     create_cc_test_files();
1730     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1731
1732     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1733
1734     r = MsiInstallProductA(msifile, NULL);
1735     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1736     {
1737         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1738         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1739         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1740         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1741         ok(delete_pf("msitest", FALSE), "File not installed\n");
1742     }
1743
1744     delete_cab_files();
1745     DeleteFile(msifile);
1746
1747     create_cc_test_files();
1748     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
1749
1750     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1751
1752     r = MsiInstallProductA(msifile, NULL);
1753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1754     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1755     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
1756     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
1757     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1758     ok(delete_pf("msitest", FALSE), "File not installed\n");
1759
1760     delete_cab_files();
1761     DeleteFile(msifile);
1762 }
1763
1764 static void test_caborder(void)
1765 {
1766     UINT r;
1767
1768     create_file("imperator", 100);
1769     create_file("maximus", 500);
1770     create_file("augustus", 50000);
1771     create_file("caesar", 500);
1772
1773     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1774
1775     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1776
1777     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1778     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1779     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1780
1781     r = MsiInstallProductA(msifile, NULL);
1782     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1783     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1784     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1785     todo_wine
1786     {
1787         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1788         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1789     }
1790
1791     delete_cab_files();
1792
1793     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1794     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1795     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1796
1797     r = MsiInstallProductA(msifile, NULL);
1798     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1799     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1800     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1801     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1802     todo_wine
1803     {
1804         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1805     }
1806
1807     delete_cab_files();
1808     DeleteFile(msifile);
1809
1810     create_cc_test_files();
1811     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1812
1813     r = MsiInstallProductA(msifile, NULL);
1814     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1815     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1816     ok(!delete_pf("msitest", FALSE), "File is installed\n");
1817     todo_wine
1818     {
1819         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1820         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1821     }
1822
1823     delete_cab_files();
1824     DeleteFile(msifile);
1825
1826     create_cc_test_files();
1827     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1828
1829     r = MsiInstallProductA(msifile, NULL);
1830     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1831     todo_wine
1832     {
1833         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1834         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1835         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1836         ok(!delete_pf("msitest", FALSE), "File is installed\n");
1837     }
1838
1839     delete_cab_files();
1840     DeleteFile("imperator");
1841     DeleteFile("maximus");
1842     DeleteFile("augustus");
1843     DeleteFile("caesar");
1844     DeleteFile(msifile);
1845 }
1846
1847 static void test_mixedmedia(void)
1848 {
1849     UINT r;
1850
1851     CreateDirectoryA("msitest", NULL);
1852     create_file("msitest\\maximus", 500);
1853     create_file("msitest\\augustus", 500);
1854     create_file("caesar", 500);
1855
1856     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1857
1858     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1859
1860     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1861
1862     r = MsiInstallProductA(msifile, NULL);
1863     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1864     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1865     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1866     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1867     ok(delete_pf("msitest", FALSE), "File not installed\n");
1868
1869     /* Delete the files in the temp (current) folder */
1870     DeleteFile("msitest\\maximus");
1871     DeleteFile("msitest\\augustus");
1872     RemoveDirectory("msitest");
1873     DeleteFile("caesar");
1874     DeleteFile("test1.cab");
1875     DeleteFile(msifile);
1876 }
1877
1878 static void test_samesequence(void)
1879 {
1880     UINT r;
1881
1882     create_cc_test_files();
1883     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1884
1885     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1886
1887     r = MsiInstallProductA(msifile, NULL);
1888     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1889     {
1890         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1891         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1892         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1893         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1894         ok(delete_pf("msitest", FALSE), "File not installed\n");
1895     }
1896
1897     delete_cab_files();
1898     DeleteFile(msifile);
1899 }
1900
1901 static void test_uiLevelFlags(void)
1902 {
1903     UINT r;
1904
1905     create_cc_test_files();
1906     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1907
1908     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1909
1910     r = MsiInstallProductA(msifile, NULL);
1911     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1912     {
1913         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1914         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1915         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1916         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1917         ok(delete_pf("msitest", FALSE), "File not installed\n");
1918     }
1919
1920     delete_cab_files();
1921     DeleteFile(msifile);
1922 }
1923
1924 static BOOL file_matches(LPSTR path)
1925 {
1926     CHAR buf[MAX_PATH];
1927     HANDLE file;
1928     DWORD size;
1929
1930     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1931                       NULL, OPEN_EXISTING, 0, NULL);
1932
1933     ZeroMemory(buf, MAX_PATH);
1934     ReadFile(file, buf, 15, &size, NULL);
1935     CloseHandle(file);
1936
1937     return !lstrcmp(buf, "msitest\\maximus");
1938 }
1939
1940 static void test_readonlyfile(void)
1941 {
1942     UINT r;
1943     DWORD size;
1944     HANDLE file;
1945     CHAR path[MAX_PATH];
1946
1947     CreateDirectoryA("msitest", NULL);
1948     create_file("msitest\\maximus", 500);
1949     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1950
1951     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1952
1953     lstrcpy(path, PROG_FILES_DIR);
1954     lstrcat(path, "\\msitest");
1955     CreateDirectory(path, NULL);
1956
1957     lstrcat(path, "\\maximus");
1958     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1959                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1960
1961     WriteFile(file, "readonlyfile", 20, &size, NULL);
1962     CloseHandle(file);
1963
1964     r = MsiInstallProductA(msifile, NULL);
1965     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1966     ok(file_matches(path), "Expected file to be overwritten\n");
1967     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1968     ok(delete_pf("msitest", FALSE), "File not installed\n");
1969
1970     /* Delete the files in the temp (current) folder */
1971     DeleteFile("msitest\\maximus");
1972     RemoveDirectory("msitest");
1973     DeleteFile(msifile);
1974 }
1975
1976 static void test_setdirproperty(void)
1977 {
1978     UINT r;
1979
1980     CreateDirectoryA("msitest", NULL);
1981     create_file("msitest\\maximus", 500);
1982     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1983
1984     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1985
1986     r = MsiInstallProductA(msifile, NULL);
1987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1988     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1989     ok(delete_cf("msitest", FALSE), "File not installed\n");
1990
1991     /* Delete the files in the temp (current) folder */
1992     DeleteFile(msifile);
1993     DeleteFile("msitest\\maximus");
1994     RemoveDirectory("msitest");
1995 }
1996
1997 static void test_cabisextracted(void)
1998 {
1999     UINT r;
2000
2001     CreateDirectoryA("msitest", NULL);
2002     create_file("msitest\\gaius", 500);
2003     create_file("maximus", 500);
2004     create_file("augustus", 500);
2005     create_file("caesar", 500);
2006
2007     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
2008     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
2009     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
2010
2011     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
2012
2013     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2014
2015     r = MsiInstallProductA(msifile, NULL);
2016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2017     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2018     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2019     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
2020     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
2021     ok(delete_pf("msitest", FALSE), "File not installed\n");
2022
2023     /* Delete the files in the temp (current) folder */
2024     delete_cab_files();
2025     DeleteFile(msifile);
2026     DeleteFile("maximus");
2027     DeleteFile("augustus");
2028     DeleteFile("caesar");
2029     DeleteFile("msitest\\gaius");
2030     RemoveDirectory("msitest");
2031 }
2032
2033 static void test_concurrentinstall(void)
2034 {
2035     UINT r;
2036     CHAR path[MAX_PATH];
2037
2038     CreateDirectoryA("msitest", NULL);
2039     CreateDirectoryA("msitest\\msitest", NULL);
2040     create_file("msitest\\maximus", 500);
2041     create_file("msitest\\msitest\\augustus", 500);
2042
2043     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
2044
2045     lstrcpyA(path, CURR_DIR);
2046     lstrcatA(path, "\\msitest\\concurrent.msi");
2047     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
2048
2049     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2050
2051     r = MsiInstallProductA(msifile, NULL);
2052     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2053     if (!delete_pf("msitest\\augustus", TRUE))
2054         trace("concurrent installs not supported\n");
2055     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2056     ok(delete_pf("msitest", FALSE), "File not installed\n");
2057
2058     DeleteFile(path);
2059
2060     r = MsiInstallProductA(msifile, NULL);
2061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2062     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2063     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2064     ok(delete_pf("msitest", FALSE), "File not installed\n");
2065
2066     DeleteFile(msifile);
2067     DeleteFile("msitest\\msitest\\augustus");
2068     DeleteFile("msitest\\maximus");
2069     RemoveDirectory("msitest\\msitest");
2070     RemoveDirectory("msitest");
2071 }
2072
2073 static void test_setpropertyfolder(void)
2074 {
2075     UINT r;
2076     CHAR path[MAX_PATH];
2077
2078     lstrcpyA(path, PROG_FILES_DIR);
2079     lstrcatA(path, "\\msitest\\added");
2080
2081     CreateDirectoryA("msitest", NULL);
2082     create_file("msitest\\maximus", 500);
2083
2084     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
2085
2086     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2087
2088     r = MsiInstallProductA(msifile, NULL);
2089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2090     if (GetFileAttributesA(path) == FILE_ATTRIBUTE_DIRECTORY)
2091     {
2092         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
2093         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
2094         ok(delete_pf("msitest", FALSE), "File not installed\n");
2095     }
2096     else
2097     {
2098         trace("changing folder property not supported\n");
2099         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2100         ok(delete_pf("msitest", FALSE), "File not installed\n");
2101     }
2102
2103     /* Delete the files in the temp (current) folder */
2104     DeleteFile(msifile);
2105     DeleteFile("msitest\\maximus");
2106     RemoveDirectory("msitest");
2107 }
2108
2109 static BOOL file_exists(LPCSTR file)
2110 {
2111     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
2112 }
2113
2114 static BOOL pf_exists(LPCSTR file)
2115 {
2116     CHAR path[MAX_PATH];
2117
2118     lstrcpyA(path, PROG_FILES_DIR);
2119     lstrcatA(path, "\\");
2120     lstrcatA(path, file);
2121
2122     return file_exists(path);
2123 }
2124
2125 static void delete_pfmsitest_files(void)
2126 {
2127     SHFILEOPSTRUCT shfl;
2128     CHAR path[MAX_PATH+11];
2129
2130     lstrcpyA(path, PROG_FILES_DIR);
2131     lstrcatA(path, "\\msitest\\*");
2132     path[strlen(path) + 1] = '\0';
2133
2134     shfl.hwnd = NULL;
2135     shfl.wFunc = FO_DELETE;
2136     shfl.pFrom = path;
2137     shfl.pTo = NULL;
2138     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
2139
2140     SHFileOperation(&shfl);
2141
2142     lstrcpyA(path, PROG_FILES_DIR);
2143     lstrcatA(path, "\\msitest");
2144     RemoveDirectoryA(path);
2145 }
2146
2147 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
2148 {
2149     char val[MAX_PATH];
2150     DWORD size, type;
2151     LONG res;
2152
2153     size = MAX_PATH;
2154     val[0] = '\0';
2155     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
2156
2157     if (res != ERROR_SUCCESS ||
2158         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
2159     {
2160         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2161         return;
2162     }
2163
2164     if (!expected)
2165         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
2166     else
2167     {
2168         if (bcase)
2169             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
2170         else
2171             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
2172     }
2173 }
2174
2175 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
2176 {
2177     DWORD val, size, type;
2178     LONG res;
2179
2180     size = sizeof(DWORD);
2181     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2182
2183     if (res != ERROR_SUCCESS || type != REG_DWORD)
2184     {
2185         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2186         return;
2187     }
2188
2189     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
2190 }
2191
2192 #define CHECK_REG_STR(prodkey, name, expected) \
2193     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2194
2195 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
2196     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
2197     RegDeleteValueA(prodkey, name);
2198
2199 #define CHECK_REG_ISTR(prodkey, name, expected) \
2200     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2201
2202 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
2203     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
2204     RegDeleteValueA(prodkey, name);
2205
2206 #define CHECK_REG_DWORD(prodkey, name, expected) \
2207     check_reg_dword(prodkey, name, expected, __LINE__);
2208
2209 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
2210     check_reg_dword(prodkey, name, expected, __LINE__); \
2211     RegDeleteValueA(prodkey, name);
2212
2213 static void get_date_str(LPSTR date)
2214 {
2215     SYSTEMTIME systime;
2216
2217     static const char date_fmt[] = "%d%02d%02d";
2218     GetLocalTime(&systime);
2219     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2220 }
2221
2222 static void test_publish_registerproduct(void)
2223 {
2224     UINT r;
2225     LONG res;
2226     HKEY hkey;
2227     HKEY props, usage;
2228     LPSTR usersid;
2229     char date[MAX_PATH];
2230     char temp[MAX_PATH];
2231     char keypath[MAX_PATH];
2232
2233     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2234                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2235     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2236                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2237     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2238                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2239     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2240                                     "\\51AAE0C44620A5E4788506E91F249BD2";
2241
2242     get_user_sid(&usersid);
2243     if (!usersid)
2244     {
2245         skip("ConvertSidToStringSidA is not available\n");
2246         return;
2247     }
2248
2249     get_date_str(date);
2250     GetTempPath(MAX_PATH, temp);
2251
2252     CreateDirectoryA("msitest", NULL);
2253     create_file("msitest\\maximus", 500);
2254
2255     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2256
2257     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2258
2259     /* RegisterProduct */
2260     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2262     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2263     ok(delete_pf("msitest", FALSE), "File not installed\n");
2264
2265     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
2266     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2267
2268     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
2269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2270
2271     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2272     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2273     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2274     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2275     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2276     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2277     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2278     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2279     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2280     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2281     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2282     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2283     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2284     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2285     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2286     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2287     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2288     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2289     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2290     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2291     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2292     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2293     todo_wine
2294     {
2295         CHECK_DEL_REG_DWORD(hkey, "EstimatedSize", 12);
2296     }
2297
2298     RegDeleteKeyA(hkey, "");
2299     RegCloseKey(hkey);
2300
2301     sprintf(keypath, userdata, usersid);
2302     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2304
2305     res = RegOpenKeyA(hkey, "InstallProperties", &props);
2306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2307
2308     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2309     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2310     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2311     CHECK_DEL_REG_STR(props, "InstallDate", date);
2312     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2313     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2314     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2315     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2316     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2317     CHECK_DEL_REG_STR(props, "Comments", NULL);
2318     CHECK_DEL_REG_STR(props, "Contact", NULL);
2319     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2320     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2321     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2322     CHECK_DEL_REG_STR(props, "Readme", NULL);
2323     CHECK_DEL_REG_STR(props, "Size", NULL);
2324     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2325     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2326     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2327     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2328     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2329     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2330     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2331     todo_wine
2332     {
2333         CHECK_DEL_REG_DWORD(props, "EstimatedSize", 12);
2334     }
2335
2336     RegDeleteKeyA(props, "");
2337     RegCloseKey(props);
2338
2339     res = RegOpenKeyA(hkey, "Usage", &usage);
2340     todo_wine
2341     {
2342         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2343     }
2344
2345     RegDeleteKeyA(usage, "");
2346     RegCloseKey(usage);
2347     RegDeleteKeyA(hkey, "");
2348     RegCloseKey(hkey);
2349
2350     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
2351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2352
2353     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2354
2355     RegDeleteKeyA(hkey, "");
2356     RegCloseKey(hkey);
2357
2358     /* RegisterProduct, machine */
2359     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
2360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2361     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2362     ok(delete_pf("msitest", FALSE), "File not installed\n");
2363
2364     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
2365     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2366
2367     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
2368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2369
2370     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2371     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2372     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2373     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2374     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2375     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2376     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2377     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2378     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2379     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2380     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2381     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2382     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2383     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2384     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2385     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2386     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2387     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2388     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2389     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2390     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2391     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2392     todo_wine
2393     {
2394         CHECK_DEL_REG_DWORD(hkey, "EstimatedSize", 12);
2395     }
2396
2397     RegDeleteKeyA(hkey, "");
2398     RegCloseKey(hkey);
2399
2400     sprintf(keypath, userdata, "S-1-5-18");
2401     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2403
2404     res = RegOpenKeyA(hkey, "InstallProperties", &props);
2405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2406
2407     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2408     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2409     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2410     CHECK_DEL_REG_STR(props, "InstallDate", date);
2411     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2412     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2413     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2414     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2415     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2416     CHECK_DEL_REG_STR(props, "Comments", NULL);
2417     CHECK_DEL_REG_STR(props, "Contact", NULL);
2418     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2419     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2420     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2421     CHECK_DEL_REG_STR(props, "Readme", NULL);
2422     CHECK_DEL_REG_STR(props, "Size", NULL);
2423     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2424     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2425     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2426     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2427     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2428     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2429     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2430     todo_wine
2431     {
2432         CHECK_DEL_REG_DWORD(props, "EstimatedSize", 12);
2433     }
2434
2435     RegDeleteKeyA(props, "");
2436     RegCloseKey(props);
2437
2438     res = RegOpenKeyA(hkey, "Usage", &usage);
2439     todo_wine
2440     {
2441         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2442     }
2443
2444     RegDeleteKeyA(usage, "");
2445     RegCloseKey(usage);
2446     RegDeleteKeyA(hkey, "");
2447     RegCloseKey(hkey);
2448
2449     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
2450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2451
2452     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2453
2454     RegDeleteKeyA(hkey, "");
2455     RegCloseKey(hkey);
2456
2457     DeleteFile(msifile);
2458     DeleteFile("msitest\\maximus");
2459     RemoveDirectory("msitest");
2460     HeapFree(GetProcessHeap(), 0, usersid);
2461 }
2462
2463 static void test_publish_publishproduct(void)
2464 {
2465     UINT r;
2466     LONG res;
2467     LPSTR usersid;
2468     HKEY sourcelist, net, props;
2469     HKEY hkey, patches, media;
2470     CHAR keypath[MAX_PATH];
2471     CHAR temp[MAX_PATH];
2472     CHAR path[MAX_PATH];
2473
2474     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2475                                    "\\Installer\\UserData\\%s\\Products"
2476                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2477     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
2478                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2479     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2480                                      "\\51AAE0C44620A5E4788506E91F249BD2";
2481     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2482                                   "\\Installer\\Products"
2483                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2484     static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2485     static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2486
2487     get_user_sid(&usersid);
2488     if (!usersid)
2489     {
2490         skip("ConvertSidToStringSidA is not available\n");
2491         return;
2492     }
2493
2494     GetTempPath(MAX_PATH, temp);
2495
2496     CreateDirectoryA("msitest", NULL);
2497     create_file("msitest\\maximus", 500);
2498
2499     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2500
2501     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2502
2503     /* PublishProduct, current user */
2504     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2506     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2507     ok(delete_pf("msitest", FALSE), "File not installed\n");
2508
2509     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
2510     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2511
2512     sprintf(keypath, prodpath, usersid);
2513     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2515
2516     res = RegOpenKeyA(hkey, "InstallProperties", &props);
2517     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2518
2519     res = RegOpenKeyA(hkey, "Patches", &patches);
2520     todo_wine
2521     {
2522         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2523
2524         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2525     }
2526
2527     RegDeleteKeyA(patches, "");
2528     RegCloseKey(patches);
2529     RegDeleteKeyA(hkey, "");
2530     RegCloseKey(hkey);
2531
2532     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
2533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2534
2535     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2536     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2537     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2538     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2539     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2540     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
2541     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2542     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2543     CHECK_DEL_REG_STR(hkey, "Clients", ":");
2544
2545     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
2546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2547
2548     lstrcpyA(path, "n;1;");
2549     lstrcatA(path, temp);
2550     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2551     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2552
2553     res = RegOpenKeyA(sourcelist, "Net", &net);
2554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2555
2556     CHECK_DEL_REG_STR(net, "1", temp);
2557
2558     RegDeleteKeyA(net, "");
2559     RegCloseKey(net);
2560
2561     res = RegOpenKeyA(sourcelist, "Media", &media);
2562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2563
2564     CHECK_DEL_REG_STR(media, "1", "DISK1;");
2565
2566     RegDeleteKeyA(media, "");
2567     RegCloseKey(media);
2568     RegDeleteKeyA(sourcelist, "");
2569     RegCloseKey(sourcelist);
2570     RegDeleteKeyA(hkey, "");
2571     RegCloseKey(hkey);
2572
2573     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
2574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2575
2576     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2577
2578     RegDeleteKeyA(hkey, "");
2579     RegCloseKey(hkey);
2580
2581     /* PublishProduct, machine */
2582     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
2583     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2584     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2585     ok(delete_pf("msitest", FALSE), "File not installed\n");
2586
2587     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
2588     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2589
2590     sprintf(keypath, prodpath, "S-1-5-18");
2591     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2593
2594     res = RegOpenKeyA(hkey, "InstallProperties", &props);
2595     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2596
2597     res = RegOpenKeyA(hkey, "Patches", &patches);
2598     todo_wine
2599     {
2600         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2601
2602         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2603     }
2604
2605     RegDeleteKeyA(patches, "");
2606     RegCloseKey(patches);
2607     RegDeleteKeyA(hkey, "");
2608     RegCloseKey(hkey);
2609
2610     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
2611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2612
2613     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2614     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2615     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2616     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2617     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2618     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
2619     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2620     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2621     CHECK_DEL_REG_STR(hkey, "Clients", ":");
2622
2623     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
2624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2625
2626     lstrcpyA(path, "n;1;");
2627     lstrcatA(path, temp);
2628     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2629     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2630
2631     res = RegOpenKeyA(sourcelist, "Net", &net);
2632     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2633
2634     CHECK_DEL_REG_STR(net, "1", temp);
2635
2636     RegDeleteKeyA(net, "");
2637     RegCloseKey(net);
2638
2639     res = RegOpenKeyA(sourcelist, "Media", &media);
2640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2641
2642     CHECK_DEL_REG_STR(media, "1", "DISK1;");
2643
2644     RegDeleteKeyA(media, "");
2645     RegCloseKey(media);
2646     RegDeleteKeyA(sourcelist, "");
2647     RegCloseKey(sourcelist);
2648     RegDeleteKeyA(hkey, "");
2649     RegCloseKey(hkey);
2650
2651     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
2652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2653
2654     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2655
2656     RegDeleteKeyA(hkey, "");
2657     RegCloseKey(hkey);
2658
2659     DeleteFile(msifile);
2660     DeleteFile("msitest\\maximus");
2661     RemoveDirectory("msitest");
2662     HeapFree(GetProcessHeap(), 0, usersid);
2663 }
2664
2665 static void test_publish_publishfeatures(void)
2666 {
2667     UINT r;
2668     LONG res;
2669     HKEY hkey;
2670     LPSTR usersid;
2671     CHAR keypath[MAX_PATH];
2672
2673     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
2674                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2675     static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2676                                  "\\Installer\\UserData\\%s\\Products"
2677                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
2678     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2679                                   "\\Installer\\Features";
2680     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
2681                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2682
2683     get_user_sid(&usersid);
2684     if (!usersid)
2685     {
2686         skip("ConvertSidToStringSidA is not available\n");
2687         return;
2688     }
2689
2690     CreateDirectoryA("msitest", NULL);
2691     create_file("msitest\\maximus", 500);
2692
2693     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2694
2695     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2696
2697     /* PublishFeatures, current user */
2698     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2700     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2701     ok(delete_pf("msitest", FALSE), "File not installed\n");
2702
2703     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
2704     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2705
2706     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
2707     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2708
2709     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
2710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2711
2712     CHECK_REG_STR(hkey, "feature", "");
2713     CHECK_REG_STR(hkey, "montecristo", "");
2714
2715     RegDeleteValueA(hkey, "feature");
2716     RegDeleteValueA(hkey, "montecristo");
2717     RegDeleteKeyA(hkey, "");
2718     RegCloseKey(hkey);
2719
2720     sprintf(keypath, udpath, usersid);
2721     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2723
2724     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
2725     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
2726
2727     RegDeleteValueA(hkey, "feature");
2728     RegDeleteValueA(hkey, "montecristo");
2729     RegDeleteKeyA(hkey, "");
2730     RegCloseKey(hkey);
2731
2732     /* PublishFeatures, machine */
2733     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
2734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2735     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2736     ok(delete_pf("msitest", FALSE), "File not installed\n");
2737
2738     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
2739     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2740
2741     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
2742     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2743
2744     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
2745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2746
2747     CHECK_REG_STR(hkey, "feature", "");
2748     CHECK_REG_STR(hkey, "montecristo", "");
2749
2750     RegDeleteValueA(hkey, "feature");
2751     RegDeleteValueA(hkey, "montecristo");
2752     RegDeleteKeyA(hkey, "");
2753     RegCloseKey(hkey);
2754
2755     sprintf(keypath, udpath, "S-1-5-18");
2756     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2757     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2758
2759     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
2760     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
2761
2762     RegDeleteValueA(hkey, "feature");
2763     RegDeleteValueA(hkey, "montecristo");
2764     RegDeleteKeyA(hkey, "");
2765     RegCloseKey(hkey);
2766
2767     DeleteFile(msifile);
2768     DeleteFile("msitest\\maximus");
2769     RemoveDirectory("msitest");
2770     HeapFree(GetProcessHeap(), 0, usersid);
2771 }
2772
2773 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
2774 {
2775     DWORD len = 0;
2776     LPSTR val;
2777     LONG r;
2778
2779     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
2780     if (r != ERROR_SUCCESS)
2781         return NULL;
2782
2783     len += sizeof (WCHAR);
2784     val = HeapAlloc(GetProcessHeap(), 0, len);
2785     if (!val) return NULL;
2786     val[0] = 0;
2787     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
2788     return val;
2789 }
2790
2791 static void get_owner_company(LPSTR *owner, LPSTR *company)
2792 {
2793     LONG res;
2794     HKEY hkey;
2795
2796     *owner = *company = NULL;
2797
2798     res = RegOpenKeyA(HKEY_CURRENT_USER,
2799                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
2800     if (res == ERROR_SUCCESS)
2801     {
2802         *owner = reg_get_val_str(hkey, "DefName");
2803         *company = reg_get_val_str(hkey, "DefCompany");
2804         RegCloseKey(hkey);
2805     }
2806
2807     if (!*owner || !*company)
2808     {
2809         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
2810                           "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
2811         if (res == ERROR_SUCCESS)
2812         {
2813             *owner = reg_get_val_str(hkey, "RegisteredOwner");
2814             *company = reg_get_val_str(hkey, "RegisteredOrganization");
2815             RegCloseKey(hkey);
2816         }
2817     }
2818
2819     if (!*owner || !*company)
2820     {
2821         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
2822                           "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
2823         if (res == ERROR_SUCCESS)
2824         {
2825             *owner = reg_get_val_str(hkey, "RegisteredOwner");
2826             *company = reg_get_val_str(hkey, "RegisteredOrganization");
2827             RegCloseKey(hkey);
2828         }
2829     }
2830 }
2831
2832 static void test_publish_registeruser(void)
2833 {
2834     UINT r;
2835     LONG res;
2836     HKEY props;
2837     LPSTR usersid;
2838     LPSTR owner, company;
2839     CHAR keypath[MAX_PATH];
2840
2841     static const CHAR keyfmt[] =
2842         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
2843         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
2844
2845     get_user_sid(&usersid);
2846     if (!usersid)
2847     {
2848         skip("ConvertSidToStringSidA is not available\n");
2849         return;
2850     }
2851
2852     get_owner_company(&owner, &company);
2853
2854     CreateDirectoryA("msitest", NULL);
2855     create_file("msitest\\maximus", 500);
2856
2857     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2858
2859     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2860
2861     /* RegisterUser, per-user */
2862     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
2863     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2864     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2865     ok(delete_pf("msitest", FALSE), "File not installed\n");
2866
2867     sprintf(keypath, keyfmt, usersid);
2868
2869     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
2870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2871
2872     CHECK_REG_STR(props, "ProductID", "none");
2873     CHECK_REG_STR(props, "RegCompany", company);
2874     CHECK_REG_STR(props, "RegOwner", owner);
2875
2876     RegDeleteValueA(props, "ProductID");
2877     RegDeleteValueA(props, "RegCompany");
2878     RegDeleteValueA(props, "RegOwner");
2879     RegDeleteKeyA(props, "");
2880     RegCloseKey(props);
2881
2882     /* RegisterUser, machine */
2883     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
2884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2885     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2886     ok(delete_pf("msitest", FALSE), "File not installed\n");
2887
2888     sprintf(keypath, keyfmt, "S-1-5-18");
2889
2890     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
2891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2892
2893     CHECK_REG_STR(props, "ProductID", "none");
2894     CHECK_REG_STR(props, "RegCompany", company);
2895     CHECK_REG_STR(props, "RegOwner", owner);
2896
2897     RegDeleteValueA(props, "ProductID");
2898     RegDeleteValueA(props, "RegCompany");
2899     RegDeleteValueA(props, "RegOwner");
2900     RegDeleteKeyA(props, "");
2901     RegCloseKey(props);
2902
2903     HeapFree(GetProcessHeap(), 0, company);
2904     HeapFree(GetProcessHeap(), 0, owner);
2905
2906     DeleteFile(msifile);
2907     DeleteFile("msitest\\maximus");
2908     RemoveDirectory("msitest");
2909 }
2910
2911 static void test_publish_processcomponents(void)
2912 {
2913     UINT r;
2914     LONG res;
2915     DWORD size;
2916     HKEY comp, hkey;
2917     LPSTR usersid;
2918     CHAR val[MAX_PATH];
2919     CHAR keypath[MAX_PATH];
2920
2921     static const CHAR keyfmt[] =
2922         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
2923         "UserData\\%s\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5";
2924     static const CHAR compkey[] =
2925         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
2926
2927     get_user_sid(&usersid);
2928     if (!usersid)
2929     {
2930         skip("ConvertSidToStringSidA is not available\n");
2931         return;
2932     }
2933
2934     CreateDirectoryA("msitest", NULL);
2935     create_file("msitest\\maximus", 500);
2936
2937     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2938
2939     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2940
2941     /* ProcessComponents, per-user */
2942     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
2943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2944     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2945     ok(delete_pf("msitest", FALSE), "File not installed\n");
2946
2947     sprintf(keypath, keyfmt, usersid);
2948
2949     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
2950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2951
2952     size = MAX_PATH;
2953     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
2954                            NULL, NULL, (LPBYTE)val, &size);
2955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2956     ok(!lstrcmpA(val, "C:\\Program Files\\msitest\\maximus"),
2957        "Expected \"%s\", got \"%s\"\n", "C:\\Program Files\\msitest\\maximus", val);
2958
2959     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
2960     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2961
2962     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
2963     RegDeleteKeyA(comp, "");
2964     RegCloseKey(comp);
2965
2966     /* ProcessComponents, machine */
2967     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
2968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2969     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2970     ok(delete_pf("msitest", FALSE), "File not installed\n");
2971
2972     sprintf(keypath, keyfmt, "S-1-5-18");
2973
2974     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
2975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2976
2977     size = MAX_PATH;
2978     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
2979                            NULL, NULL, (LPBYTE)val, &size);
2980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2981     ok(!lstrcmpA(val, "C:\\Program Files\\msitest\\maximus"),
2982        "Expected \"%s\", got \"%s\"\n", "C:\\Program Files\\msitest\\maximus", val);
2983
2984     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
2985     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2986
2987     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
2988     RegDeleteKeyA(comp, "");
2989     RegCloseKey(comp);
2990
2991     DeleteFile(msifile);
2992     DeleteFile("msitest\\maximus");
2993     RemoveDirectory("msitest");
2994 }
2995
2996 static void test_publish(void)
2997 {
2998     UINT r;
2999     LONG res;
3000     HKEY uninstall, prodkey;
3001     INSTALLSTATE state;
3002     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3003     char date[MAX_PATH];
3004     char temp[MAX_PATH];
3005
3006     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3007
3008     if (!pMsiQueryComponentStateA)
3009     {
3010         skip("MsiQueryComponentStateA is not available\n");
3011         return;
3012     }
3013
3014     get_date_str(date);
3015     GetTempPath(MAX_PATH, temp);
3016
3017     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
3018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3019
3020     CreateDirectoryA("msitest", NULL);
3021     create_file("msitest\\maximus", 500);
3022
3023     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3024
3025     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3026
3027     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3028     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3029
3030     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3031     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3032
3033     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3034     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3035
3036     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3037                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3038     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3039     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3040
3041     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3042     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3043
3044     /* nothing published */
3045     r = MsiInstallProductA(msifile, NULL);
3046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3047     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3048     ok(pf_exists("msitest"), "File not installed\n");
3049
3050     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3051     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3052
3053     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3054     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3055
3056     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3057     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3058
3059     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3060                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3061     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3062     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3063
3064     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3065     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3066
3067     /* PublishProduct and RegisterProduct */
3068     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
3069     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3070     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3071     ok(pf_exists("msitest"), "File not installed\n");
3072
3073     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3074     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3075
3076     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3077     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3078
3079     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3080     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3081
3082     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3083                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3084     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3085     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3086
3087     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3088     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3089
3090     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3091     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3092     CHECK_REG_STR(prodkey, "InstallDate", date);
3093     CHECK_REG_STR(prodkey, "InstallSource", temp);
3094     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3095     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3096     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3097     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3098     CHECK_REG_STR(prodkey, "Comments", NULL);
3099     CHECK_REG_STR(prodkey, "Contact", NULL);
3100     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3101     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3102     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3103     CHECK_REG_STR(prodkey, "Readme", NULL);
3104     CHECK_REG_STR(prodkey, "Size", NULL);
3105     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3106     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3107     CHECK_REG_DWORD(prodkey, "Language", 1033);
3108     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3109     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3110     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3111     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3112     todo_wine
3113     {
3114         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3115     }
3116
3117     RegCloseKey(prodkey);
3118
3119     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3121     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3122     ok(pf_exists("msitest"), "File deleted\n");
3123
3124     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3125     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3126
3127     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3128     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3129
3130     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3131     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3132
3133     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3134                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3135     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3136     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3137
3138     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3139     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3140
3141     /* complete install */
3142     r = MsiInstallProductA(msifile, "FULL=1");
3143     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3144     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3145     ok(pf_exists("msitest"), "File not installed\n");
3146
3147     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3148     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3149
3150     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3151     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3152
3153     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3154     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3155
3156     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3157                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3159     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3160
3161     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3163
3164     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3165     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3166     CHECK_REG_STR(prodkey, "InstallDate", date);
3167     CHECK_REG_STR(prodkey, "InstallSource", temp);
3168     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3169     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3170     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3171     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3172     CHECK_REG_STR(prodkey, "Comments", NULL);
3173     CHECK_REG_STR(prodkey, "Contact", NULL);
3174     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3175     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3176     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3177     CHECK_REG_STR(prodkey, "Readme", NULL);
3178     CHECK_REG_STR(prodkey, "Size", NULL);
3179     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3180     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3181     CHECK_REG_DWORD(prodkey, "Language", 1033);
3182     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3183     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3184     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3185     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3186     todo_wine
3187     {
3188         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3189     }
3190
3191     RegCloseKey(prodkey);
3192
3193     /* no UnpublishFeatures */
3194     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3196     todo_wine
3197     {
3198         ok(!pf_exists("msitest\\maximus"), "File deleted\n");
3199         ok(!pf_exists("msitest"), "File deleted\n");
3200     }
3201
3202     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3203     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3204
3205     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3206     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3207
3208     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3209     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3210
3211     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3212                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3213     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3214     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3215
3216     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3217     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3218
3219     /* complete install */
3220     r = MsiInstallProductA(msifile, "FULL=1");
3221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3222     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3223     ok(pf_exists("msitest"), "File not installed\n");
3224
3225     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3226     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3227
3228     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3229     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3230
3231     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3232     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3233
3234     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3235                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3237     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3238
3239     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3241
3242     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3243     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3244     CHECK_REG_STR(prodkey, "InstallDate", date);
3245     CHECK_REG_STR(prodkey, "InstallSource", temp);
3246     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3247     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3248     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3249     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3250     CHECK_REG_STR(prodkey, "Comments", NULL);
3251     CHECK_REG_STR(prodkey, "Contact", NULL);
3252     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3253     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3254     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3255     CHECK_REG_STR(prodkey, "Readme", NULL);
3256     CHECK_REG_STR(prodkey, "Size", NULL);
3257     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3258     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3259     CHECK_REG_DWORD(prodkey, "Language", 1033);
3260     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3261     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3262     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3263     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3264     todo_wine
3265     {
3266         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3267     }
3268
3269     RegCloseKey(prodkey);
3270
3271     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
3272     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
3273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3274     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3275     ok(pf_exists("msitest"), "File deleted\n");
3276
3277     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3278     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3279
3280     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3281     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3282
3283     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3284     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3285
3286     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3287                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3289     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3290
3291     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3292     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3293
3294     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3295     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3296     CHECK_REG_STR(prodkey, "InstallDate", date);
3297     CHECK_REG_STR(prodkey, "InstallSource", temp);
3298     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3299     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3300     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3301     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3302     CHECK_REG_STR(prodkey, "Comments", NULL);
3303     CHECK_REG_STR(prodkey, "Contact", NULL);
3304     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3305     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3306     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3307     CHECK_REG_STR(prodkey, "Readme", NULL);
3308     CHECK_REG_STR(prodkey, "Size", NULL);
3309     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3310     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3311     CHECK_REG_DWORD(prodkey, "Language", 1033);
3312     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3313     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3314     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3315     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3316     todo_wine
3317     {
3318         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3319     }
3320
3321     RegCloseKey(prodkey);
3322
3323     /* complete install */
3324     r = MsiInstallProductA(msifile, "FULL=1");
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3327     ok(pf_exists("msitest"), "File not installed\n");
3328
3329     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3330     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3331
3332     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3333     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3334
3335     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3336     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3337
3338     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3339                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3341     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3342
3343     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3345
3346     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3347     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3348     CHECK_REG_STR(prodkey, "InstallDate", date);
3349     CHECK_REG_STR(prodkey, "InstallSource", temp);
3350     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3351     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3352     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3353     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3354     CHECK_REG_STR(prodkey, "Comments", NULL);
3355     CHECK_REG_STR(prodkey, "Contact", NULL);
3356     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3357     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3358     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3359     CHECK_REG_STR(prodkey, "Readme", NULL);
3360     CHECK_REG_STR(prodkey, "Size", NULL);
3361     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3362     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3363     CHECK_REG_DWORD(prodkey, "Language", 1033);
3364     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3365     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3366     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3367     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3368     todo_wine
3369     {
3370         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3371     }
3372
3373     RegCloseKey(prodkey);
3374
3375     /* UnpublishFeatures, both features removed */
3376     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
3377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3378     todo_wine
3379     {
3380         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3381         ok(!pf_exists("msitest"), "File not deleted\n");
3382     }
3383
3384     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3385     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3386
3387     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3388     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3389
3390     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3391     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3392
3393     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3394                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3395     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3396     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3397
3398     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3399     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3400
3401     /* complete install */
3402     r = MsiInstallProductA(msifile, "FULL=1");
3403     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3404     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3405     ok(pf_exists("msitest"), "File not installed\n");
3406
3407     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3408     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3409
3410     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3411     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3412
3413     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3414     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3415
3416     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3417                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3418     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3419     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3420
3421     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3423
3424     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3425     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3426     CHECK_REG_STR(prodkey, "InstallDate", date);
3427     CHECK_REG_STR(prodkey, "InstallSource", temp);
3428     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3429     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3430     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3431     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3432     CHECK_REG_STR(prodkey, "Comments", NULL);
3433     CHECK_REG_STR(prodkey, "Contact", NULL);
3434     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3435     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3436     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3437     CHECK_REG_STR(prodkey, "Readme", NULL);
3438     CHECK_REG_STR(prodkey, "Size", NULL);
3439     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3440     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3441     CHECK_REG_DWORD(prodkey, "Language", 1033);
3442     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3443     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3444     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3445     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3446     todo_wine
3447     {
3448         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3449     }
3450
3451     RegCloseKey(prodkey);
3452
3453     /* complete uninstall */
3454     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3455     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3456     todo_wine
3457     {
3458         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3459         ok(!pf_exists("msitest"), "File not deleted\n");
3460     }
3461
3462     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3463     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3464
3465     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3466     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3467
3468     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3469     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3470
3471     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3472                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3473     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3474     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3475
3476     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3477     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3478
3479     /* make sure 'Program Files\msitest' is removed */
3480     delete_pfmsitest_files();
3481
3482     RegCloseKey(uninstall);
3483     DeleteFile(msifile);
3484     DeleteFile("msitest\\maximus");
3485     RemoveDirectory("msitest");
3486 }
3487
3488 static void test_publishsourcelist(void)
3489 {
3490     UINT r;
3491     DWORD size;
3492     CHAR value[MAX_PATH];
3493     CHAR path[MAX_PATH];
3494     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3495
3496     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
3497     {
3498         skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
3499         return;
3500     }
3501
3502     CreateDirectoryA("msitest", NULL);
3503     create_file("msitest\\maximus", 500);
3504
3505     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3506
3507     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3508
3509     r = MsiInstallProductA(msifile, NULL);
3510     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3511     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3512     ok(pf_exists("msitest"), "File not installed\n");
3513
3514     /* nothing published */
3515     size = 0xdeadbeef;
3516     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3517                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3518     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3519     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3520
3521     size = 0xdeadbeef;
3522     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3523                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3524     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3525     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3526
3527     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
3528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3529     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3530     ok(pf_exists("msitest"), "File not installed\n");
3531
3532     /* after RegisterProduct */
3533     size = 0xdeadbeef;
3534     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3535                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3536     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3537     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3538
3539     size = 0xdeadbeef;
3540     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3541                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3542     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3543     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3544
3545     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3546     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3547     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3548     ok(pf_exists("msitest"), "File not installed\n");
3549
3550     /* after ProcessComponents */
3551     size = 0xdeadbeef;
3552     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3553                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3554     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3555     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3556
3557     size = 0xdeadbeef;
3558     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3559                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3560     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3561     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3562
3563     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3564     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3565     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3566     ok(pf_exists("msitest"), "File not installed\n");
3567
3568     /* after PublishFeatures */
3569     size = 0xdeadbeef;
3570     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3571                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3572     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3573     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3574
3575     size = 0xdeadbeef;
3576     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3577                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3578     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3579     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3580
3581     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3583     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3584     ok(pf_exists("msitest"), "File not installed\n");
3585
3586     /* after PublishProduct */
3587     size = MAX_PATH;
3588     lstrcpyA(value, "aaa");
3589     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3590                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
3591     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3592     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
3593     ok(size == 11, "Expected 11, got %d\n", size);
3594
3595     size = MAX_PATH;
3596     lstrcpyA(value, "aaa");
3597     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3598                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
3599     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3600     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3601     ok(size == 0, "Expected 0, got %d\n", size);
3602
3603     size = MAX_PATH;
3604     lstrcpyA(value, "aaa");
3605     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3606                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
3607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3608     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3609     ok(size == 0, "Expected 0, got %d\n", size);
3610
3611     lstrcpyA(path, CURR_DIR);
3612     lstrcatA(path, "\\");
3613
3614     size = MAX_PATH;
3615     lstrcpyA(value, "aaa");
3616     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3617                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3619     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3620     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3621
3622     size = MAX_PATH;
3623     lstrcpyA(value, "aaa");
3624     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3625                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
3626     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3627     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
3628     ok(size == 1, "Expected 1, got %d\n", size);
3629
3630     size = MAX_PATH;
3631     lstrcpyA(value, "aaa");
3632     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3633                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
3634     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3635     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3636     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3637
3638     size = MAX_PATH;
3639     lstrcpyA(value, "aaa");
3640     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3641                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
3642     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3643     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3644     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3645
3646     size = MAX_PATH;
3647     lstrcpyA(value, "aaa");
3648     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3649                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
3650     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3651     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3652     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3653
3654     /* complete uninstall */
3655     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3657     todo_wine
3658     {
3659         ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3660         ok(!pf_exists("msitest"), "File not deleted\n");
3661     }
3662
3663     /* make sure 'Program Files\msitest' is removed */
3664     delete_pfmsitest_files();
3665
3666     DeleteFile(msifile);
3667     DeleteFile("msitest\\maximus");
3668     RemoveDirectory("msitest");
3669 }
3670
3671 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
3672 {
3673     MSIHANDLE hview = 0;
3674     UINT r;
3675
3676     r = MsiDatabaseOpenView(hdb, query, &hview);
3677     if(r != ERROR_SUCCESS)
3678         return r;
3679
3680     r = MsiViewExecute(hview, hrec);
3681     if(r == ERROR_SUCCESS)
3682         r = MsiViewClose(hview);
3683     MsiCloseHandle(hview);
3684     return r;
3685 }
3686
3687 static void set_transform_summary_info(void)
3688 {
3689     UINT r;
3690     MSIHANDLE suminfo = 0;
3691
3692     /* build summary info */
3693     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
3694     todo_wine
3695     {
3696         ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
3697     }
3698
3699     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3700     todo_wine
3701     {
3702         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3703     }
3704
3705     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3706                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3707                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3708                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
3709     todo_wine
3710     {
3711         ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
3712     }
3713
3714     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3715     todo_wine
3716     {
3717         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3718     }
3719
3720     r = MsiSummaryInfoPersist(suminfo);
3721     todo_wine
3722     {
3723         ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
3724     }
3725
3726     r = MsiCloseHandle(suminfo);
3727     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
3728 }
3729
3730 static void generate_transform(void)
3731 {
3732     MSIHANDLE hdb1, hdb2;
3733     LPCSTR query;
3734     UINT r;
3735
3736     /* start with two identical databases */
3737     CopyFile(msifile, msifile2, FALSE);
3738
3739     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
3740     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3741
3742     r = MsiDatabaseCommit(hdb1);
3743     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
3744
3745     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
3746     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3747
3748     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
3749     r = run_query(hdb1, 0, query);
3750     ok(r == ERROR_SUCCESS, "failed to add property\n");
3751
3752     /* database needs to be committed */
3753     MsiDatabaseCommit(hdb1);
3754
3755     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
3756     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
3757
3758 #if 0  /* not implemented in wine yet */
3759     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
3760     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3761 #endif
3762
3763     MsiCloseHandle(hdb1);
3764     MsiCloseHandle(hdb2);
3765 }
3766
3767 /* data for generating a transform */
3768
3769 /* tables transform names - encoded as they would be in an msi database file */
3770 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3771 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3772 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3773
3774 /* data in each table */
3775 static const char data1[] = /* _StringData */
3776     "propval";  /* all the strings squashed together */
3777
3778 static const WCHAR data2[] = { /* _StringPool */
3779 /*  len, refs */
3780     0,   0,    /* string 0 ''     */
3781     4,   1,    /* string 1 'prop' */
3782     3,   1,    /* string 2 'val'  */
3783 };
3784
3785 static const WCHAR data3[] = { /* Property */
3786     0x0201, 0x0001, 0x0002,
3787 };
3788
3789 static const struct {
3790     LPCWSTR name;
3791     const void *data;
3792     DWORD size;
3793 } table_transform_data[] =
3794 {
3795     { name1, data1, sizeof data1 - 1 },
3796     { name2, data2, sizeof data2 },
3797     { name3, data3, sizeof data3 },
3798 };
3799
3800 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
3801
3802 static void generate_transform_manual(void)
3803 {
3804     IStorage *stg = NULL;
3805     IStream *stm;
3806     WCHAR name[0x20];
3807     HRESULT r;
3808     DWORD i, count;
3809     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
3810
3811     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
3812
3813     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
3814
3815     r = StgCreateDocfile(name, mode, 0, &stg);
3816     ok(r == S_OK, "failed to create storage\n");
3817     if (!stg)
3818         return;
3819
3820     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
3821     ok(r == S_OK, "failed to set storage type\n");
3822
3823     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
3824     {
3825         r = IStorage_CreateStream(stg, table_transform_data[i].name,
3826                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3827         if (FAILED(r))
3828         {
3829             ok(0, "failed to create stream %08x\n", r);
3830             continue;
3831         }
3832
3833         r = IStream_Write(stm, table_transform_data[i].data,
3834                           table_transform_data[i].size, &count);
3835         if (FAILED(r) || count != table_transform_data[i].size)
3836             ok(0, "failed to write stream\n");
3837         IStream_Release(stm);
3838     }
3839
3840     IStorage_Release(stg);
3841
3842     set_transform_summary_info();
3843 }
3844
3845 static void test_transformprop(void)
3846 {
3847     UINT r;
3848
3849     CreateDirectoryA("msitest", NULL);
3850     create_file("msitest\\augustus", 500);
3851
3852     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
3853
3854     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3855
3856     r = MsiInstallProductA(msifile, NULL);
3857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3858     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3859     ok(!delete_pf("msitest", FALSE), "File installed\n");
3860
3861     if (0)
3862         generate_transform();
3863     else
3864         generate_transform_manual();
3865
3866     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
3867     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3868     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3869     ok(delete_pf("msitest", FALSE), "File not installed\n");
3870
3871     /* Delete the files in the temp (current) folder */
3872     DeleteFile(msifile);
3873     DeleteFile(msifile2);
3874     DeleteFile(mstfile);
3875     DeleteFile("msitest\\augustus");
3876     RemoveDirectory("msitest");
3877 }
3878
3879 static void test_currentworkingdir(void)
3880 {
3881     UINT r;
3882     CHAR path[MAX_PATH];
3883     LPSTR ptr, ptr2;
3884
3885     CreateDirectoryA("msitest", NULL);
3886     create_file("msitest\\augustus", 500);
3887
3888     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
3889
3890     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3891
3892     CreateDirectoryA("diffdir", NULL);
3893     SetCurrentDirectoryA("diffdir");
3894
3895     sprintf(path, "..\\%s", msifile);
3896     r = MsiInstallProductA(path, NULL);
3897     todo_wine
3898     {
3899         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
3900         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3901         ok(!delete_pf("msitest", FALSE), "File installed\n");
3902     }
3903
3904     sprintf(path, "%s\\%s", CURR_DIR, msifile);
3905     r = MsiInstallProductA(path, NULL);
3906     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3907     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3908     ok(delete_pf("msitest", FALSE), "File not installed\n");
3909
3910     lstrcpyA(path, CURR_DIR);
3911     if (path[lstrlenA(path) - 1] != '\\')
3912         lstrcatA(path, "\\");
3913     lstrcatA(path, "msitest.msi");
3914
3915     ptr2 = strrchr(path, '\\');
3916     *ptr2 = '\0';
3917     ptr = strrchr(path, '\\');
3918     *ptr2 = '\\';
3919     *(ptr++) = '\0';
3920
3921     SetCurrentDirectoryA(path);
3922
3923     r = MsiInstallProductA(ptr, NULL);
3924     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3925     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3926     ok(delete_pf("msitest", FALSE), "File not installed\n");
3927
3928     SetCurrentDirectoryA(CURR_DIR);
3929
3930     DeleteFile(msifile);
3931     DeleteFile("msitest\\augustus");
3932     RemoveDirectory("msitest");
3933     RemoveDirectory("diffdir");
3934 }
3935
3936 static void set_admin_summary_info(const CHAR *name)
3937 {
3938     MSIHANDLE db, summary;
3939     UINT r;
3940
3941     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
3942     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3943
3944     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
3945     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3946
3947     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
3948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3949
3950     /* write the summary changes back to the stream */
3951     r = MsiSummaryInfoPersist(summary);
3952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3953
3954     MsiCloseHandle(summary);
3955
3956     r = MsiDatabaseCommit(db);
3957     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3958
3959     MsiCloseHandle(db);
3960 }
3961
3962 static void test_admin(void)
3963 {
3964     UINT r;
3965
3966     CreateDirectoryA("msitest", NULL);
3967     create_file("msitest\\augustus", 500);
3968
3969     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
3970     set_admin_summary_info(msifile);
3971
3972     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3973
3974     r = MsiInstallProductA(msifile, NULL);
3975     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3976     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3977     ok(!delete_pf("msitest", FALSE), "File installed\n");
3978     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
3979     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
3980
3981     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
3982     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3983     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3984     ok(!delete_pf("msitest", FALSE), "File installed\n");
3985     todo_wine
3986     {
3987         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
3988         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
3989     }
3990
3991     DeleteFile(msifile);
3992     DeleteFile("msitest\\augustus");
3993     RemoveDirectory("msitest");
3994 }
3995
3996 static void set_admin_property_stream(LPCSTR file)
3997 {
3998     IStorage *stg;
3999     IStream *stm;
4000     WCHAR fileW[MAX_PATH];
4001     HRESULT hr;
4002     DWORD count;
4003     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
4004
4005     /* AdminProperties */
4006     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
4007     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
4008
4009     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
4010
4011     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
4012     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4013     if (!stg)
4014         return;
4015
4016     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4017     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4018
4019     hr = IStream_Write(stm, data, sizeof(data), &count);
4020     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4021
4022     IStream_Release(stm);
4023     IStorage_Release(stg);
4024 }
4025
4026 static void test_adminprops(void)
4027 {
4028     UINT r;
4029
4030     CreateDirectoryA("msitest", NULL);
4031     create_file("msitest\\augustus", 500);
4032
4033     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
4034     set_admin_summary_info(msifile);
4035     set_admin_property_stream(msifile);
4036
4037     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4038
4039     r = MsiInstallProductA(msifile, NULL);
4040     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4041     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4042     ok(delete_pf("msitest", FALSE), "File installed\n");
4043
4044     DeleteFile(msifile);
4045     DeleteFile("msitest\\augustus");
4046     RemoveDirectory("msitest");
4047 }
4048
4049 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4050 {
4051     CHAR path[MAX_PATH];
4052
4053     lstrcpyA(path, PROG_FILES_DIR);
4054     lstrcatA(path, "\\");
4055     lstrcatA(path, file);
4056
4057     if (is_file)
4058         create_file_data(path, data, 500);
4059     else
4060         CreateDirectoryA(path, NULL);
4061 }
4062
4063 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4064
4065 static void test_removefiles(void)
4066 {
4067     UINT r;
4068
4069     CreateDirectoryA("msitest", NULL);
4070     create_file("msitest\\hydrogen", 500);
4071     create_file("msitest\\helium", 500);
4072     create_file("msitest\\lithium", 500);
4073
4074     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4075
4076     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4077
4078     r = MsiInstallProductA(msifile, NULL);
4079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4080     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4081     ok(!pf_exists("msitest\\helium"), "File installed\n");
4082     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4083     ok(pf_exists("msitest"), "File not installed\n");
4084
4085     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4086     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4087     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4088     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4089     todo_wine
4090     {
4091         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4092         ok(delete_pf("msitest", FALSE), "File deleted\n");
4093     }
4094
4095     create_pf("msitest", FALSE);
4096     create_pf("msitest\\hydrogen", TRUE);
4097     create_pf("msitest\\helium", TRUE);
4098     create_pf("msitest\\lithium", TRUE);
4099
4100     r = MsiInstallProductA(msifile, NULL);
4101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4102     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4103     ok(pf_exists("msitest\\helium"), "File not installed\n");
4104     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4105     ok(pf_exists("msitest"), "File not installed\n");
4106
4107     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4109     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4110     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4111     todo_wine
4112     {
4113         ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4114         ok(delete_pf("msitest", FALSE), "File deleted\n");
4115     }
4116
4117     create_pf("msitest", FALSE);
4118     create_pf("msitest\\furlong", TRUE);
4119     create_pf("msitest\\firkin", TRUE);
4120     create_pf("msitest\\fortnight", TRUE);
4121     create_pf("msitest\\becquerel", TRUE);
4122     create_pf("msitest\\dioptre", TRUE);
4123     create_pf("msitest\\attoparsec", TRUE);
4124     create_pf("msitest\\storeys", TRUE);
4125     create_pf("msitest\\block", TRUE);
4126     create_pf("msitest\\siriometer", TRUE);
4127
4128     r = MsiInstallProductA(msifile, NULL);
4129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4130     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4131     ok(!pf_exists("msitest\\helium"), "File installed\n");
4132     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4133     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4134     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4135     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4136     ok(pf_exists("msitest"), "File not installed\n");
4137     todo_wine
4138     {
4139         ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4140         ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4141         ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4142         ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4143         ok(!pf_exists("msitest\\block"), "File not deleted\n");
4144         ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4145     }
4146
4147     create_pf("msitest\\furlong", TRUE);
4148     create_pf("msitest\\firkin", TRUE);
4149     create_pf("msitest\\fortnight", TRUE);
4150     create_pf("msitest\\storeys", TRUE);
4151     create_pf("msitest\\block", TRUE);
4152     create_pf("msitest\\siriometer", TRUE);
4153
4154     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4155     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4156     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4157     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4158     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4159     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4160     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4161     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4162     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4163     todo_wine
4164     {
4165         ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4166         ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4167         ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4168         ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4169         ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4170     }
4171     ok(delete_pf("msitest", FALSE), "File deleted\n");
4172
4173     DeleteFile(msifile);
4174     DeleteFile("msitest\\hydrogen");
4175     DeleteFile("msitest\\helium");
4176     DeleteFile("msitest\\lithium");
4177     RemoveDirectory("msitest");
4178 }
4179
4180 static void test_movefiles(void)
4181 {
4182     UINT r;
4183     char props[MAX_PATH];
4184
4185     CreateDirectoryA("msitest", NULL);
4186     create_file("msitest\\augustus", 100);
4187     create_file("cameroon", 100);
4188     create_file("djibouti", 100);
4189     create_file("egypt", 100);
4190     create_file("finland", 100);
4191     create_file("gambai", 100);
4192     create_file("honduras", 100);
4193     create_file("msitest\\india", 100);
4194     create_file("japan", 100);
4195     create_file("kenya", 100);
4196     CreateDirectoryA("latvia", NULL);
4197     create_file("nauru", 100);
4198     create_file("apple", 100);
4199     create_file("application", 100);
4200     create_file("ape", 100);
4201     create_file("foo", 100);
4202     create_file("fao", 100);
4203     create_file("fbod", 100);
4204     create_file("budding", 100);
4205     create_file("buddy", 100);
4206     create_file("bud", 100);
4207     create_file("bar", 100);
4208     create_file("bur", 100);
4209     create_file("bird", 100);
4210
4211     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4212
4213     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4214
4215     /* if the source or dest property is not a full path,
4216      * windows tries to access it as a network resource
4217      */
4218
4219     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4220             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4221             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4222
4223     r = MsiInstallProductA(msifile, props);
4224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4225     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4226     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4227     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4228     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4229     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4230     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4231     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4232     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4233     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4234     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4235     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4236     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4237     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4238     /* either apple or application will be moved depending on directory order */
4239     if (!delete_pf("msitest\\apple", TRUE))
4240         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4241     else
4242         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4243     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4244     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4245     /* either fao or foo will be moved depending on directory order */
4246     if (delete_pf("msitest\\foo", TRUE))
4247         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4248     else
4249         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4250     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4251     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4252     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4253     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4254     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4255     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4256     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4257     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4258     ok(delete_pf("msitest", FALSE), "File not installed\n");
4259     ok(DeleteFileA("cameroon"), "File moved\n");
4260     ok(!DeleteFileA("djibouti"), "File not moved\n");
4261     ok(DeleteFileA("egypt"), "File moved\n");
4262     ok(DeleteFileA("finland"), "File moved\n");
4263     ok(DeleteFileA("gambai"), "File moved\n");
4264     ok(!DeleteFileA("honduras"), "File not moved\n");
4265     ok(DeleteFileA("msitest\\india"), "File moved\n");
4266     ok(DeleteFileA("japan"), "File moved\n");
4267     ok(!DeleteFileA("kenya"), "File not moved\n");
4268     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4269     ok(!DeleteFileA("nauru"), "File not moved\n");
4270     ok(!DeleteFileA("apple"), "File not moved\n");
4271     ok(!DeleteFileA("application"), "File not moved\n");
4272     ok(DeleteFileA("ape"), "File moved\n");
4273     ok(!DeleteFileA("foo"), "File not moved\n");
4274     ok(!DeleteFileA("fao"), "File not moved\n");
4275     ok(DeleteFileA("fbod"), "File moved\n");
4276     ok(!DeleteFileA("budding"), "File not moved\n");
4277     ok(!DeleteFileA("buddy"), "File not moved\n");
4278     ok(DeleteFileA("bud"), "File moved\n");
4279     ok(!DeleteFileA("bar"), "File not moved\n");
4280     ok(!DeleteFileA("bur"), "File not moved\n");
4281     ok(DeleteFileA("bird"), "File moved\n");
4282
4283     DeleteFile("msitest\\augustus");
4284     RemoveDirectory("msitest");
4285     DeleteFile(msifile);
4286 }
4287
4288 static void test_missingcab(void)
4289 {
4290     UINT r;
4291
4292     CreateDirectoryA("msitest", NULL);
4293     create_file("msitest\\augustus", 500);
4294     create_file("maximus", 500);
4295
4296     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
4297
4298     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4299
4300     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4301
4302     create_pf("msitest", FALSE);
4303     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4304
4305     r = MsiInstallProductA(msifile, NULL);
4306     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4307     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4308     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4309     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4310     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
4311     ok(delete_pf("msitest", FALSE), "File not installed\n");
4312
4313     create_pf("msitest", FALSE);
4314     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4315     create_pf("msitest\\gaius", TRUE);
4316
4317     r = MsiInstallProductA(msifile, "GAIUS=1");
4318     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4319     todo_wine
4320     {
4321         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
4322         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4323     }
4324     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
4325     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
4326     ok(delete_pf("msitest", FALSE), "File not installed\n");
4327
4328     DeleteFile("msitest\\augustus");
4329     RemoveDirectory("msitest");
4330     DeleteFile("maximus");
4331     DeleteFile("test1.cab");
4332     DeleteFile(msifile);
4333 }
4334
4335 static void test_duplicatefiles(void)
4336 {
4337     UINT r;
4338
4339     CreateDirectoryA("msitest", NULL);
4340     create_file("msitest\\maximus", 500);
4341     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4342
4343     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4344
4345     /* fails if the destination folder is not a valid property */
4346
4347     r = MsiInstallProductA(msifile, NULL);
4348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4349     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4350     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4351     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4352     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
4353     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
4354     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
4355     ok(delete_pf("msitest", FALSE), "File not installed\n");
4356
4357     DeleteFile("msitest\\maximus");
4358     RemoveDirectory("msitest");
4359     DeleteFile(msifile);
4360 }
4361
4362 static void test_writeregistryvalues(void)
4363 {
4364     UINT r;
4365     LONG res;
4366     HKEY hkey;
4367     DWORD type, size;
4368     CHAR path[MAX_PATH];
4369
4370     CreateDirectoryA("msitest", NULL);
4371     create_file("msitest\\augustus", 500);
4372
4373     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4374
4375     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4376
4377     r = MsiInstallProductA(msifile, NULL);
4378     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4379     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4380     ok(delete_pf("msitest", FALSE), "File installed\n");
4381
4382     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
4383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4384
4385     size = MAX_PATH;
4386     type = REG_MULTI_SZ;
4387     memset(path, 'a', MAX_PATH);
4388     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4390     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4391     ok(size == 15, "Expected 15, got %d\n", size);
4392     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4393
4394     DeleteFile(msifile);
4395     DeleteFile("msitest\\augustus");
4396     RemoveDirectory("msitest");
4397
4398     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
4399     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
4400 }
4401
4402 static void test_sourcefolder(void)
4403 {
4404     UINT r;
4405
4406     CreateDirectoryA("msitest", NULL);
4407     create_file("augustus", 500);
4408
4409     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
4410
4411     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4412
4413     r = MsiInstallProductA(msifile, NULL);
4414     ok(r == ERROR_INSTALL_FAILURE,
4415        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4416     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4417     todo_wine
4418     {
4419         ok(!delete_pf("msitest", FALSE), "File installed\n");
4420     }
4421
4422     RemoveDirectoryA("msitest");
4423
4424     r = MsiInstallProductA(msifile, NULL);
4425     ok(r == ERROR_INSTALL_FAILURE,
4426        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4427     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4428     todo_wine
4429     {
4430         ok(!delete_pf("msitest", FALSE), "File installed\n");
4431     }
4432
4433     DeleteFile(msifile);
4434     DeleteFile("augustus");
4435 }
4436
4437 static void test_customaction51(void)
4438 {
4439     UINT r;
4440
4441     CreateDirectoryA("msitest", NULL);
4442     create_file("msitest\\augustus", 500);
4443
4444     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
4445
4446     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4447
4448     r = MsiInstallProductA(msifile, NULL);
4449     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4450     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4451     ok(delete_pf("msitest", FALSE), "File installed\n");
4452
4453     DeleteFile(msifile);
4454     DeleteFile("msitest\\augustus");
4455     RemoveDirectory("msitest");
4456 }
4457
4458 static void test_installstate(void)
4459 {
4460     UINT r;
4461
4462     CreateDirectoryA("msitest", NULL);
4463     create_file("msitest\\alpha", 500);
4464     create_file("msitest\\beta", 500);
4465     create_file("msitest\\gamma", 500);
4466     create_file("msitest\\theta", 500);
4467     create_file("msitest\\delta", 500);
4468     create_file("msitest\\epsilon", 500);
4469     create_file("msitest\\zeta", 500);
4470     create_file("msitest\\iota", 500);
4471     create_file("msitest\\eta", 500);
4472     create_file("msitest\\kappa", 500);
4473     create_file("msitest\\lambda", 500);
4474     create_file("msitest\\mu", 500);
4475
4476     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
4477
4478     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4479
4480     r = MsiInstallProductA(msifile, NULL);
4481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4482     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4483     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4484     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4485     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4486     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4487     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4488     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4489     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4490     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4491     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4492     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4493     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4494     ok(delete_pf("msitest", FALSE), "File not installed\n");
4495
4496     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
4497     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4498     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4499     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4500     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4501     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4502     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4503     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
4504     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4505     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4506     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
4507     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4508     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4509     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4510     ok(delete_pf("msitest", FALSE), "File not installed\n");
4511
4512     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
4513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4514     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4515     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4516     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4517     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4518     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4519     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4520     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4521     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4522     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4523     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4524     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4525     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4526     ok(delete_pf("msitest", FALSE), "File not installed\n");
4527
4528     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
4529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4530     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
4531     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4532     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4533     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
4534     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4535     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4536     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4537     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4538     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4539     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4540     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4541     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4542     ok(!delete_pf("msitest", FALSE), "File installed\n");
4543
4544     DeleteFile(msifile);
4545     DeleteFile("msitest\\alpha");
4546     DeleteFile("msitest\\beta");
4547     DeleteFile("msitest\\gamma");
4548     DeleteFile("msitest\\theta");
4549     DeleteFile("msitest\\delta");
4550     DeleteFile("msitest\\epsilon");
4551     DeleteFile("msitest\\zeta");
4552     DeleteFile("msitest\\iota");
4553     DeleteFile("msitest\\eta");
4554     DeleteFile("msitest\\kappa");
4555     DeleteFile("msitest\\lambda");
4556     DeleteFile("msitest\\mu");
4557     RemoveDirectory("msitest");
4558 }
4559
4560 START_TEST(install)
4561 {
4562     DWORD len;
4563     char temp_path[MAX_PATH], prev_path[MAX_PATH];
4564
4565     init_functionpointers();
4566
4567     GetCurrentDirectoryA(MAX_PATH, prev_path);
4568     GetTempPath(MAX_PATH, temp_path);
4569     SetCurrentDirectoryA(temp_path);
4570
4571     lstrcpyA(CURR_DIR, temp_path);
4572     len = lstrlenA(CURR_DIR);
4573
4574     if(len && (CURR_DIR[len - 1] == '\\'))
4575         CURR_DIR[len - 1] = 0;
4576
4577     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
4578
4579     test_MsiInstallProduct();
4580     test_MsiSetComponentState();
4581     test_packagecoltypes();
4582     test_continuouscabs();
4583     test_caborder();
4584     test_mixedmedia();
4585     test_samesequence();
4586     test_uiLevelFlags();
4587     test_readonlyfile();
4588     test_setdirproperty();
4589     test_cabisextracted();
4590     test_concurrentinstall();
4591     test_setpropertyfolder();
4592     test_publish_registerproduct();
4593     test_publish_publishproduct();
4594     test_publish_publishfeatures();
4595     test_publish_registeruser();
4596     test_publish_processcomponents();
4597     test_publish();
4598     test_publishsourcelist();
4599     test_transformprop();
4600     test_currentworkingdir();
4601     test_admin();
4602     test_adminprops();
4603     test_removefiles();
4604     test_movefiles();
4605     test_missingcab();
4606     test_duplicatefiles();
4607     test_writeregistryvalues();
4608     test_sourcefolder();
4609     test_customaction51();
4610     test_installstate();
4611
4612     SetCurrentDirectoryA(prev_path);
4613 }