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 #include <shlobj.h>
33 #include <winsvc.h>
34 #include <shellapi.h>
35 
36 #include "wine/test.h"
37 #include "utils.h"
38 
39 static BOOL is_wow64;
40 static const BOOL is_64bit = sizeof(void *) > sizeof(int);
41 
42 static const char *msifile = "msitest.msi";
43 static const char *msifile2 = "winetest2.msi";
44 static const char *mstfile = "winetest.mst";
45 
46 static const WCHAR msifileW[] = L"msitest.msi";
47 static const WCHAR msifile2W[] = L"msitest2.msi";
48 
49 char CURR_DIR[MAX_PATH];
50 char PROG_FILES_DIR[MAX_PATH];
51 char PROG_FILES_DIR_NATIVE[MAX_PATH];
52 char COMMON_FILES_DIR[MAX_PATH];
53 char APP_DATA_DIR[MAX_PATH];
54 char WINDOWS_DIR[MAX_PATH];
55 
56 static const char *customdll;
57 
58 /* msi database data */
59 
60 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
61                                     "s72\tS38\ts72\ti2\tS255\tS72\n"
62                                     "Component\tComponent\n"
63                                     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
64                                     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
65                                     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
66                                     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
67                                     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
68                                     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
69                                     "component\t\tMSITESTDIR\t0\t1\tfile\n";
70 
71 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
72                                     "s72\tS72\tl255\n"
73                                     "Directory\tDirectory\n"
74                                     "CABOUTDIR\tMSITESTDIR\tcabout\n"
75                                     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
76                                     "FIRSTDIR\tMSITESTDIR\tfirst\n"
77                                     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
78                                     "NEWDIR\tCABOUTDIR\tnew\n"
79                                     "ProgramFilesFolder\tTARGETDIR\t.\n"
80                                     "TARGETDIR\t\tSourceDir";
81 
82 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
83                                   "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
84                                   "Feature\tFeature\n"
85                                   "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
86                                   "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
87                                   "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
88                                   "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
89                                   "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
90                                   "feature\t\t\t\t2\t1\tTARGETDIR\t0\n";
91 
92 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
93                                        "s38\ts72\n"
94                                        "FeatureComponents\tFeature_\tComponent_\n"
95                                        "Five\tFive\n"
96                                        "Four\tFour\n"
97                                        "One\tOne\n"
98                                        "Three\tThree\n"
99                                        "Two\tTwo\n"
100                                        "feature\tcomponent\n";
101 
102 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
103                                "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
104                                "File\tFile\n"
105                                "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
106                                "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
107                                "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
108                                "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
109                                "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
110                                "file\tcomponent\tfilename\t100\t\t\t8192\t1\n";
111 
112 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
113                                            "s72\tS255\tI2\n"
114                                            "InstallExecuteSequence\tAction\n"
115                                            "AllocateRegistrySpace\tNOT Installed\t1550\n"
116                                            "CostFinalize\t\t1000\n"
117                                            "CostInitialize\t\t800\n"
118                                            "FileCost\t\t900\n"
119                                            "ResolveSource\t\t950\n"
120                                            "MoveFiles\t\t1700\n"
121                                            "InstallFiles\t\t4000\n"
122                                            "BindImage\t\t4100\n"
123                                            "DuplicateFiles\t\t4500\n"
124                                            "WriteEnvironmentStrings\t\t4550\n"
125                                            "CreateShortcuts\t\t4600\n"
126                                            "InstallFinalize\t\t6600\n"
127                                            "InstallInitialize\t\t1500\n"
128                                            "InstallValidate\t\t1400\n"
129                                            "LaunchConditions\t\t100\n"
130                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
131 
132 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
133                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
134                                 "Media\tDiskId\n"
135                                 "1\t3\t\t\tDISK1\t\n"
136                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
137 
138 static const CHAR property_dat[] = "Property\tValue\n"
139                                    "s72\tl0\n"
140                                    "Property\tProperty\n"
141                                    "DefaultUIFont\tDlgFont8\n"
142                                    "HASUIRUN\t0\n"
143                                    "INSTALLLEVEL\t3\n"
144                                    "InstallMode\tTypical\n"
145                                    "Manufacturer\tWine\n"
146                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
147                                    "PRIMARYFOLDER\tTARGETDIR\n"
148                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
149                                    "ProductID\tnone\n"
150                                    "ProductLanguage\t1033\n"
151                                    "ProductName\tMSITEST\n"
152                                    "ProductVersion\t1.1.1\n"
153                                    "PROMPTROLLBACKCOST\tP\n"
154                                    "Setup\tSetup\n"
155                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
156                                    "AdminProperties\tPOSTADMIN\n"
157                                    "ROOTDRIVE\tC:\\\n"
158                                    "MSIFASTINSTALL\t1\n";
159 
160 static const CHAR aup_property_dat[] = "Property\tValue\n"
161                                        "s72\tl0\n"
162                                        "Property\tProperty\n"
163                                        "DefaultUIFont\tDlgFont8\n"
164                                        "HASUIRUN\t0\n"
165                                        "ALLUSERS\t1\n"
166                                        "INSTALLLEVEL\t3\n"
167                                        "InstallMode\tTypical\n"
168                                        "Manufacturer\tWine\n"
169                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
170                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
171                                        "ProductID\tnone\n"
172                                        "ProductLanguage\t1033\n"
173                                        "ProductName\tMSITEST\n"
174                                        "ProductVersion\t1.1.1\n"
175                                        "PROMPTROLLBACKCOST\tP\n"
176                                        "Setup\tSetup\n"
177                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
178                                        "AdminProperties\tPOSTADMIN\n"
179                                        "ROOTDRIVE\tC:\\\n"
180                                        "MSIFASTINSTALL\t1\n";
181 
182 static const CHAR aup2_property_dat[] = "Property\tValue\n"
183                                         "s72\tl0\n"
184                                         "Property\tProperty\n"
185                                         "DefaultUIFont\tDlgFont8\n"
186                                         "HASUIRUN\t0\n"
187                                         "ALLUSERS\t2\n"
188                                         "INSTALLLEVEL\t3\n"
189                                         "InstallMode\tTypical\n"
190                                         "Manufacturer\tWine\n"
191                                         "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
192                                         "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
193                                         "ProductID\tnone\n"
194                                         "ProductLanguage\t1033\n"
195                                         "ProductName\tMSITEST\n"
196                                         "ProductVersion\t1.1.1\n"
197                                         "PROMPTROLLBACKCOST\tP\n"
198                                         "Setup\tSetup\n"
199                                         "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
200                                         "AdminProperties\tPOSTADMIN\n"
201                                         "ROOTDRIVE\tC:\\\n"
202                                         "MSIFASTINSTALL\t1\n";
203 
204 static const CHAR icon_property_dat[] = "Property\tValue\n"
205                                         "s72\tl0\n"
206                                         "Property\tProperty\n"
207                                         "DefaultUIFont\tDlgFont8\n"
208                                         "HASUIRUN\t0\n"
209                                         "INSTALLLEVEL\t3\n"
210                                         "InstallMode\tTypical\n"
211                                         "Manufacturer\tWine\n"
212                                         "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
213                                         "ProductCode\t{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}\n"
214                                         "ProductID\tnone\n"
215                                         "ProductLanguage\t1033\n"
216                                         "ProductName\tMSITEST\n"
217                                         "ProductVersion\t1.1.1\n"
218                                         "PROMPTROLLBACKCOST\tP\n"
219                                         "Setup\tSetup\n"
220                                         "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
221                                         "AdminProperties\tPOSTADMIN\n"
222                                         "ROOTDRIVE\tC:\\\n"
223                                         "MSIFASTINSTALL\t1\n";
224 
225 static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
226                                    "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
227                                    "Shortcut\tShortcut\n"
228                                    "Shortcut\tMSITESTDIR\tShortcut\tcomponent\tShortcut\t\tShortcut\t\t\t\t\t\n";
229 
230 static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n"
231                                     "s38\ti2\tS255\n"
232                                     "Condition\tFeature_\tLevel\n"
233                                     "One\t4\t1\n";
234 
235 static const CHAR up_property_dat[] = "Property\tValue\n"
236                                       "s72\tl0\n"
237                                       "Property\tProperty\n"
238                                       "DefaultUIFont\tDlgFont8\n"
239                                       "HASUIRUN\t0\n"
240                                       "INSTALLLEVEL\t3\n"
241                                       "InstallMode\tTypical\n"
242                                       "Manufacturer\tWine\n"
243                                       "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
244                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
245                                       "ProductID\tnone\n"
246                                       "ProductLanguage\t1033\n"
247                                       "ProductName\tMSITEST\n"
248                                       "ProductVersion\t1.1.1\n"
249                                       "PROMPTROLLBACKCOST\tP\n"
250                                       "Setup\tSetup\n"
251                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
252                                       "AdminProperties\tPOSTADMIN\n"
253                                       "ROOTDRIVE\tC:\\\n"
254                                       "RemovePreviousVersions\t1\n"
255                                       "MSIFASTINSTALL\t1\n";
256 
257 static const CHAR up2_property_dat[] = "Property\tValue\n"
258                                        "s72\tl0\n"
259                                        "Property\tProperty\n"
260                                        "DefaultUIFont\tDlgFont8\n"
261                                        "HASUIRUN\t0\n"
262                                        "INSTALLLEVEL\t3\n"
263                                        "InstallMode\tTypical\n"
264                                        "Manufacturer\tWine\n"
265                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
266                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
267                                        "ProductID\tnone\n"
268                                        "ProductLanguage\t1033\n"
269                                        "ProductName\tMSITEST\n"
270                                        "ProductVersion\t1.1.2\n"
271                                        "PROMPTROLLBACKCOST\tP\n"
272                                        "Setup\tSetup\n"
273                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
274                                        "AdminProperties\tPOSTADMIN\n"
275                                        "ROOTDRIVE\tC:\\\n"
276                                        "MSIFASTINSTALL\t1\n";
277 
278 static const CHAR up3_property_dat[] = "Property\tValue\n"
279                                        "s72\tl0\n"
280                                        "Property\tProperty\n"
281                                        "DefaultUIFont\tDlgFont8\n"
282                                        "HASUIRUN\t0\n"
283                                        "INSTALLLEVEL\t3\n"
284                                        "InstallMode\tTypical\n"
285                                        "Manufacturer\tWine\n"
286                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
287                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
288                                        "ProductID\tnone\n"
289                                        "ProductLanguage\t1033\n"
290                                        "ProductName\tMSITEST\n"
291                                        "ProductVersion\t1.1.2\n"
292                                        "PROMPTROLLBACKCOST\tP\n"
293                                        "Setup\tSetup\n"
294                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
295                                        "AdminProperties\tPOSTADMIN\n"
296                                        "ROOTDRIVE\tC:\\\n"
297                                        "RemovePreviousVersions\t1\n"
298                                        "MSIFASTINSTALL\t1\n";
299 
300 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
301                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
302                                    "Registry\tRegistry\n"
303                                    "Apples\t1\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
304                                    "Oranges\t1\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
305                                    "regdata\t1\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
306                                    "OrderTest\t1\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
307 
308 /* tables for test_continuouscabs */
309 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
310                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
311                                        "Component\tComponent\n"
312                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
313                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
314                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
315 
316 static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
317                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
318                                         "Component\tComponent\n"
319                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
320                                         "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
321                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
322 
323 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
324                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
325                                      "Feature\tFeature\n"
326                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
327 
328 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
329                                           "s38\ts72\n"
330                                           "FeatureComponents\tFeature_\tComponent_\n"
331                                           "feature\tmaximus\n"
332                                           "feature\taugustus\n"
333                                           "feature\tcaesar";
334 
335 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
336                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
337                                   "File\tFile\n"
338                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
339                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
340                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
341 
342 static const CHAR cc2_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                                    "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
348                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
349 
350 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
351                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
352                                    "Media\tDiskId\n"
353                                    "1\t10\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 cc3_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
358                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
359                                     "Media\tDiskId\n"
360                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
361                                     "2\t2\t\ttest2_.cab\tDISK2\t\n"
362                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
363 
364 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
365                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
366                                   "File\tFile\n"
367                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
368                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
369                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
370 
371 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
372                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
373                                    "Media\tDiskId\n"
374                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
375                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
376                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
377 
378 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
379                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
380                                     "Media\tDiskId\n"
381                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
382                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
383                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
384 
385 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
386                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
387                                   "File\tFile\n"
388                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
389                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
390                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
391 
392 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
393                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
394                                    "Media\tDiskId\n"
395                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
396 
397 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
398                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
399                                    "Media\tDiskId\n"
400                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
401                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
402                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
403 
404 /* tables for test_uiLevelFlags */
405 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
406                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
407                                        "Component\tComponent\n"
408                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
409                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
410                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
411 
412 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
413                                            "s72\tS255\tI2\n"
414                                            "InstallUISequence\tAction\n"
415                                            "SetUIProperty\t\t5\n"
416                                            "ExecuteAction\t\t1100\n";
417 
418 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
419                                            "s72\ti2\tS64\tS0\tS255\n"
420                                            "CustomAction\tAction\n"
421                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
422 
423 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
424                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
425                                         "Component\tComponent\n"
426                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
427 
428 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
429                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
430                                       "Feature\tFeature\n"
431                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
432                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
433 
434 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
435                                            "s38\ts72\n"
436                                            "FeatureComponents\tFeature_\tComponent_\n"
437                                            "feature\tmaximus\n"
438                                            "montecristo\tmaximus";
439 
440 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
441                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
442                                    "File\tFile\n"
443                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
444 
445 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
446                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
447                                     "Media\tDiskId\n"
448                                     "1\t1\t\t\tDISK1\t\n";
449 
450 static const CHAR rofc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
451                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
452                                     "File\tFile\n"
453                                     "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1";
454 
455 static const CHAR rofc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
456                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
457                                      "Media\tDiskId\n"
458                                      "1\t1\t\ttest1.cab\tDISK1\t\n";
459 
460 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
461                                                "s72\tS255\tI2\n"
462                                                "InstallExecuteSequence\tAction\n"
463                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
464                                                "CostFinalize\t\t1000\n"
465                                                "CostInitialize\t\t800\n"
466                                                "FileCost\t\t900\n"
467                                                "InstallFiles\t\t4000\n"
468                                                "InstallFinalize\t\t6600\n"
469                                                "InstallInitialize\t\t1500\n"
470                                                "InstallValidate\t\t1400\n"
471                                                "LaunchConditions\t\t100\n"
472                                                "SetDirProperty\t\t950";
473 
474 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
475                                             "s72\ti2\tS64\tS0\tS255\n"
476                                             "CustomAction\tAction\n"
477                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
478 
479 static const CHAR pv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
480                                               "s72\tS255\tI2\n"
481                                               "InstallExecuteSequence\tAction\n"
482                                               "LaunchConditions\t\t100\n"
483                                               "CostInitialize\t\t800\n"
484                                               "FileCost\t\t900\n"
485                                               "CostFinalize\t\t1000\n"
486                                               "InstallValidate\t\t1400\n"
487                                               "InstallInitialize\t\t1500\n"
488                                               "InstallFiles\t\t4000\n"
489                                               "InstallFinalize\t\t6600\n";
490 
491 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
492                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
493                                         "Component\tComponent\n"
494                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
495                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
496                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
497                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
498 
499 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
500                                            "s38\ts72\n"
501                                            "FeatureComponents\tFeature_\tComponent_\n"
502                                            "feature\tmaximus\n"
503                                            "feature\taugustus\n"
504                                            "feature\tcaesar\n"
505                                            "feature\tgaius";
506 
507 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
508                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
509                                    "File\tFile\n"
510                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
511                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
512                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
513                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
514 
515 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
516                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
517                                     "Media\tDiskId\n"
518                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
519                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
520                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
521 
522 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
523                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
524                                        "Component\tComponent\n"
525                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
526 
527 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
528                                            "s38\ts72\n"
529                                            "FeatureComponents\tFeature_\tComponent_\n"
530                                            "feature\taugustus";
531 
532 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
533                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
534                                    "File\tFile\n"
535                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
536 
537 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
538                                               "s72\tS255\tI2\n"
539                                               "InstallExecuteSequence\tAction\n"
540                                               "ValidateProductID\t\t700\n"
541                                               "CostInitialize\t\t800\n"
542                                               "FileCost\t\t900\n"
543                                               "CostFinalize\t\t1000\n"
544                                               "InstallValidate\t\t1400\n"
545                                               "InstallInitialize\t\t1500\n"
546                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
547                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
548                                               "RemoveFiles\t\t3500\n"
549                                               "InstallFiles\t\t4000\n"
550                                               "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
551                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
552                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
553                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
554                                               "InstallFinalize\t\t6600";
555 
556 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
557                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
558                                        "Component\tComponent\n"
559                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
560 
561 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
562                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
563                                         "Component\tComponent\n"
564                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
565 
566 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
567                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
568                                         "Component\tComponent\n"
569                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
570 
571 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
572                                             "s72\ti2\tS64\tS0\tS255\n"
573                                             "CustomAction\tAction\n"
574                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
575 
576 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
577                                              "s72\tS255\tI2\n"
578                                              "AdminExecuteSequence\tAction\n"
579                                              "CostFinalize\t\t1000\n"
580                                              "CostInitialize\t\t800\n"
581                                              "FileCost\t\t900\n"
582                                              "SetPOSTADMIN\t\t950\n"
583                                              "InstallFiles\t\t4000\n"
584                                              "InstallFinalize\t\t6600\n"
585                                              "InstallInitialize\t\t1500\n"
586                                              "InstallValidate\t\t1400\n"
587                                              "LaunchConditions\t\t100";
588 
589 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
590                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
591                                         "Component\tComponent\n"
592                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718 and MyProp=42\taugustus\n";
593 
594 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
595                                                "s72\tS255\tI2\n"
596                                                "InstallExecuteSequence\tAction\n"
597                                                "ValidateProductID\t\t700\n"
598                                                "CostInitialize\t\t800\n"
599                                                "FileCost\t\t900\n"
600                                                "CostFinalize\t\t1000\n"
601                                                "InstallValidate\t\t1400\n"
602                                                "InstallInitialize\t\t1500\n"
603                                                "ProcessComponents\t\t1600\n"
604                                                "UnpublishFeatures\t\t1800\n"
605                                                "RemoveFiles\t\t3500\n"
606                                                "InstallFiles\t\t4000\n"
607                                                "RegisterProduct\t\t6100\n"
608                                                "PublishFeatures\t\t6300\n"
609                                                "PublishProduct\t\t6400\n"
610                                                "InstallFinalize\t\t6600";
611 
612 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
613                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
614                                         "Component\tComponent\n"
615                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
616                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
617                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
618                                         "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n"
619                                         "tiberius\t\tMSITESTDIR\t0\t\ttiberius\n";
620 
621 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
622                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
623                                   "File\tFile\n"
624                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
625                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
626                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
627                                   "gaius\tgaius\tgaius\t500\t\t\t16384\t4\n"
628                                   "tiberius\ttiberius\ttiberius\t500\t\t\t0\t5\n";
629 
630 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
631                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
632                                    "Media\tDiskId\n"
633                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
634                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
635                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
636                                    "4\t4\t\ttest3.cab\tDISK3\t\n"
637                                    "5\t5\t\ttest4.cab\tDISK4\t\n";
638 
639 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
640                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
641                                        "MsiFileHash\tFile_\n"
642                                        "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
643 
644 static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
645                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
646                                         "Component\tComponent\n"
647                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
648 
649 static const CHAR ca1_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
650                                                "s72\tS255\tI2\n"
651                                                "InstallExecuteSequence\tAction\n"
652                                                "CostInitialize\t\t100\n"
653                                                "FileCost\t\t200\n"
654                                                "CostFinalize\t\t300\n"
655                                                "InstallValidate\t\t400\n"
656                                                "InstallInitialize\t\t500\n"
657                                                "embednull\t\t600\n"
658                                                "maintest\tMAIN_TEST\t700\n"
659                                                "testretval\tTEST_RETVAL\t710\n"
660                                                "process1\tTEST_PROCESS\t720\n"
661                                                "process2\tTEST_PROCESS\t721\n"
662                                                "process_deferred\tTEST_PROCESS\t722\n"
663                                                "async1\tTEST_ASYNC\t730\n"
664                                                "async2\tTEST_ASYNC\t731\n"
665                                                "InstallFinalize\t\t800\n";
666 
667 static const CHAR ca1_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
668                                              "s72\ti2\tS64\tS0\n"
669                                              "CustomAction\tAction\n"
670                                              "embednull\t51\tembednullprop\ta[~]b\n"
671                                              "nested51\t51\tnested\t1\n"
672                                              "nested1\t1\tcustom.dll\tnested\n"
673                                              "maintest\t1\tcustom.dll\tmain_test\n"
674                                              "process1\t1\tcustom.dll\tprocess1\n"
675                                              "process2\t1\tcustom.dll\tprocess2\n"
676                                              "process_deferred\t1025\tcustom.dll\tprocess2\n"
677                                              "async1\t129\tcustom.dll\tasync1\n"
678                                              "async2\t1\tcustom.dll\tasync2\n"
679                                              "testretval\t1\tcustom.dll\ttest_retval\n";
680 
681 static const CHAR ca1_test_seq_dat[] = "Action\tCondition\tSequence\n"
682                                        "s72\tS255\tI2\n"
683                                        "TestSequence\tAction\n"
684                                        "nested1\t\t1\n"
685                                        "nested51\t\t2\n";
686 
687 static const CHAR ca1_test2_dat[] =
688     "A\tB\n"
689     "i2\ti2\n"
690     "test2\tA\n"
691     "1\t2\n";
692 
693 static const CHAR ca1__validation_dat[] =
694     "Table\tColumn\tNullable\tMinValue\tMaxValue\tKeyTable\tKeyColumn\tCategory\tSet\tDescription\n"
695     "s32\ts32\ts4\tI4\tI4\tS255\tI2\tS32\tS255\tS255\n"
696     "_Validation\tTable\tColumn\n"
697     "test2\tA\tN\t\t\t\t\t\t\t\n"
698     "test2\tB\tN\t\t\t\t\t\t\t\n";
699 
700 static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
701                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
702                                          "Component\tComponent\n"
703                                          "augustus\t\tMSITESTDIR\t0\tMYPROP=42\taugustus\n";
704 
705 static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
706                                                 "s72\tS255\tI2\n"
707                                                 "InstallExecuteSequence\tAction\n"
708                                                 "ValidateProductID\t\t700\n"
709                                                 "GoodSetProperty\t\t725\n"
710                                                 "BadSetProperty\t\t750\n"
711                                                 "CostInitialize\t\t800\n"
712                                                 "ResolveSource\t\t810\n"
713                                                 "FileCost\t\t900\n"
714                                                 "SetSourceDir\tSRCDIR\t910\n"
715                                                 "CostFinalize\t\t1000\n"
716                                                 "InstallValidate\t\t1400\n"
717                                                 "InstallInitialize\t\t1500\n"
718                                                 "InstallFiles\t\t4000\n"
719                                                 "InstallFinalize\t\t6600";
720 
721 static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
722                                              "s72\ti2\tS64\tS0\n"
723                                              "CustomAction\tAction\n"
724                                              "GoodSetProperty\t51\tMYPROP\t42\n"
725                                              "BadSetProperty\t51\t\tMYPROP\n"
726                                              "SetSourceDir\t51\tSourceDir\t[SRCDIR]\n";
727 
728 static const CHAR is_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
729                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
730                                      "Feature\tFeature\n"
731                                      "one\t\t\t\t2\t1\t\t0\n" /* favorLocal */
732                                      "two\t\t\t\t2\t1\t\t1\n" /* favorSource */
733                                      "three\t\t\t\t2\t1\t\t4\n" /* favorAdvertise */
734                                      "four\t\t\t\t2\t0\t\t0"; /* disabled */
735 
736 static const CHAR is_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
737                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
738                                        "Component\tComponent\n"
739                                        "alpha\t\tMSITESTDIR\t0\t\talpha_file\n" /* favorLocal:Local */
740                                        "beta\t\tMSITESTDIR\t1\t\tbeta_file\n" /* favorLocal:Source */
741                                        "gamma\t\tMSITESTDIR\t2\t\tgamma_file\n" /* favorLocal:Optional */
742                                        "theta\t\tMSITESTDIR\t0\t\ttheta_file\n" /* favorSource:Local */
743                                        "delta\t\tMSITESTDIR\t1\t\tdelta_file\n" /* favorSource:Source */
744                                        "epsilon\t\tMSITESTDIR\t2\t\tepsilon_file\n" /* favorSource:Optional */
745                                        "zeta\t\tMSITESTDIR\t0\t\tzeta_file\n" /* favorAdvertise:Local */
746                                        "iota\t\tMSITESTDIR\t1\t\tiota_file\n" /* favorAdvertise:Source */
747                                        "eta\t\tMSITESTDIR\t2\t\teta_file\n" /* favorAdvertise:Optional */
748                                        "kappa\t\tMSITESTDIR\t0\t\tkappa_file\n" /* disabled:Local */
749                                        "lambda\t\tMSITESTDIR\t1\t\tlambda_file\n" /* disabled:Source */
750                                        "mu\t\tMSITESTDIR\t2\t\tmu_file\n"; /* disabled:Optional */
751 
752 static const CHAR is_feature_comp_dat[] = "Feature_\tComponent_\n"
753                                           "s38\ts72\n"
754                                           "FeatureComponents\tFeature_\tComponent_\n"
755                                           "one\talpha\n"
756                                           "one\tbeta\n"
757                                           "one\tgamma\n"
758                                           "two\ttheta\n"
759                                           "two\tdelta\n"
760                                           "two\tepsilon\n"
761                                           "three\tzeta\n"
762                                           "three\tiota\n"
763                                           "three\teta\n"
764                                           "four\tkappa\n"
765                                           "four\tlambda\n"
766                                           "four\tmu";
767 
768 static const CHAR is_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
769                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
770                                   "File\tFile\n"
771                                   "alpha_file\talpha\talpha\t500\t\t\t8192\t1\n"
772                                   "beta_file\tbeta\tbeta\t500\t\t\t8291\t2\n"
773                                   "gamma_file\tgamma\tgamma\t500\t\t\t8192\t3\n"
774                                   "theta_file\ttheta\ttheta\t500\t\t\t8192\t4\n"
775                                   "delta_file\tdelta\tdelta\t500\t\t\t8192\t5\n"
776                                   "epsilon_file\tepsilon\tepsilon\t500\t\t\t8192\t6\n"
777                                   "zeta_file\tzeta\tzeta\t500\t\t\t8192\t7\n"
778                                   "iota_file\tiota\tiota\t500\t\t\t8192\t8\n"
779                                   "eta_file\teta\teta\t500\t\t\t8192\t9\n"
780                                   "kappa_file\tkappa\tkappa\t500\t\t\t8192\t10\n"
781                                   "lambda_file\tlambda\tlambda\t500\t\t\t8192\t11\n"
782                                   "mu_file\tmu\tmu\t500\t\t\t8192\t12";
783 
784 static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
785                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
786                                    "Media\tDiskId\n"
787                                    "1\t12\t\t\tDISK1\t\n";
788 
789 static const CHAR sp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
790                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
791                                         "Component\tComponent\n"
792                                         "augustus\t\tTWODIR\t0\t\taugustus\n";
793 
794 static const CHAR sp_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
795                                        "s72\tS72\tl255\n"
796                                        "Directory\tDirectory\n"
797                                        "TARGETDIR\t\tSourceDir\n"
798                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
799                                        "MSITESTDIR\tProgramFilesFolder\tmsitest:.\n"
800                                        "ONEDIR\tMSITESTDIR\t.:shortone|longone\n"
801                                        "TWODIR\tONEDIR\t.:shorttwo|longtwo";
802 
803 static const CHAR mcp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
804                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
805                                         "Component\tComponent\n"
806                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
807                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
808                                         "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
809 
810 static const CHAR mcp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
811                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
812                                       "Feature\tFeature\n"
813                                       "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
814                                       "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
815                                       "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
816 
817 static const CHAR mcp_feature_comp_dat[] = "Feature_\tComponent_\n"
818                                            "s38\ts72\n"
819                                            "FeatureComponents\tFeature_\tComponent_\n"
820                                            "hydroxyl\thydrogen\n"
821                                            "heliox\thelium\n"
822                                            "lithia\tlithium";
823 
824 static const CHAR mcp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
825                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
826                                    "File\tFile\n"
827                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
828                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
829                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1\n"
830                                    "beryllium\tmissingcomp\tberyllium\t0\t\t\t8192\t1";
831 
832 static const CHAR ai_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
833                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
834                                   "File\tFile\n"
835                                   "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
836                                   "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
837                                   "one.txt\tOne\tone.txt\t1000\t\t\t16384\t1\n"
838                                   "three.txt\tThree\tthree.txt\t1000\t\t\t16384\t3\n"
839                                   "two.txt\tTwo\ttwo.txt\t1000\t\t\t16384\t2\n"
840                                   "file\tcomponent\tfilename\t100\t\t\t8192\t1\n";
841 
842 static const CHAR ip_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
843                                               "s72\tS255\tI2\n"
844                                               "InstallExecuteSequence\tAction\n"
845                                               "CostFinalize\t\t1000\n"
846                                               "ValidateProductID\t\t700\n"
847                                               "CostInitialize\t\t800\n"
848                                               "FileCost\t\t900\n"
849                                               "RemoveFiles\t\t3500\n"
850                                               "InstallFiles\t\t4000\n"
851                                               "RegisterUser\t\t6000\n"
852                                               "RegisterProduct\t\t6100\n"
853                                               "PublishFeatures\t\t6300\n"
854                                               "PublishProduct\t\t6400\n"
855                                               "InstallFinalize\t\t6600\n"
856                                               "InstallInitialize\t\t1500\n"
857                                               "ProcessComponents\t\t1600\n"
858                                               "UnpublishFeatures\t\t1800\n"
859                                               "InstallValidate\t\t1400\n"
860                                               "LaunchConditions\t\t100\n"
861                                               "TestInstalledProp\tInstalled AND NOT REMOVE\t950\n";
862 
863 static const CHAR ip_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
864                                            "s72\ti2\tS64\tS0\tS255\n"
865                                            "CustomAction\tAction\n"
866                                            "TestInstalledProp\t19\t\tTest failed\t\n";
867 
868 static const CHAR aup_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
869                                                "s72\tS255\tI2\n"
870                                                "InstallExecuteSequence\tAction\n"
871                                                "CostFinalize\t\t1000\n"
872                                                "ValidateProductID\t\t700\n"
873                                                "CostInitialize\t\t800\n"
874                                                "FileCost\t\t900\n"
875                                                "RemoveFiles\t\t3500\n"
876                                                "InstallFiles\t\t4000\n"
877                                                "RegisterUser\t\t6000\n"
878                                                "RegisterProduct\t\t6100\n"
879                                                "PublishFeatures\t\t6300\n"
880                                                "PublishProduct\t\t6400\n"
881                                                "InstallFinalize\t\t6600\n"
882                                                "InstallInitialize\t\t1500\n"
883                                                "ProcessComponents\t\t1600\n"
884                                                "UnpublishFeatures\t\t1800\n"
885                                                "InstallValidate\t\t1400\n"
886                                                "LaunchConditions\t\t100\n"
887                                                "TestAllUsersProp\tALLUSERS AND NOT REMOVE\t50\n";
888 
889 static const CHAR aup2_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
890                                                 "s72\tS255\tI2\n"
891                                                 "InstallExecuteSequence\tAction\n"
892                                                 "CostFinalize\t\t1000\n"
893                                                 "ValidateProductID\t\t700\n"
894                                                 "CostInitialize\t\t800\n"
895                                                 "FileCost\t\t900\n"
896                                                 "RemoveFiles\t\t3500\n"
897                                                 "InstallFiles\t\t4000\n"
898                                                 "RegisterUser\t\t6000\n"
899                                                 "RegisterProduct\t\t6100\n"
900                                                 "PublishFeatures\t\t6300\n"
901                                                 "PublishProduct\t\t6400\n"
902                                                 "InstallFinalize\t\t6600\n"
903                                                 "InstallInitialize\t\t1500\n"
904                                                 "ProcessComponents\t\t1600\n"
905                                                 "UnpublishFeatures\t\t1800\n"
906                                                 "InstallValidate\t\t1400\n"
907                                                 "LaunchConditions\t\t100\n"
908                                                 "TestAllUsersProp\tALLUSERS=2 AND NOT REMOVE\t50\n";
909 
910 static const CHAR aup3_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
911                                                 "s72\tS255\tI2\n"
912                                                 "InstallExecuteSequence\tAction\n"
913                                                 "CostFinalize\t\t1000\n"
914                                                 "ValidateProductID\t\t700\n"
915                                                 "CostInitialize\t\t800\n"
916                                                 "FileCost\t\t900\n"
917                                                 "RemoveFiles\t\t3500\n"
918                                                 "InstallFiles\t\t4000\n"
919                                                 "RegisterUser\t\t6000\n"
920                                                 "RegisterProduct\t\t6100\n"
921                                                 "PublishFeatures\t\t6300\n"
922                                                 "PublishProduct\t\t6400\n"
923                                                 "InstallFinalize\t\t6600\n"
924                                                 "InstallInitialize\t\t1500\n"
925                                                 "ProcessComponents\t\t1600\n"
926                                                 "UnpublishFeatures\t\t1800\n"
927                                                 "InstallValidate\t\t1400\n"
928                                                 "LaunchConditions\t\t100\n"
929                                                 "TestAllUsersProp\tALLUSERS=1 AND NOT REMOVE\t50\n";
930 
931 static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
932                                             "s72\ti2\tS64\tS0\tS255\n"
933                                             "CustomAction\tAction\n"
934                                             "TestAllUsersProp\t19\t\tTest failed\t\n";
935 
936 static const CHAR fo_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
937                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
938                                   "File\tFile\n"
939                                   "override.txt\toverride\toverride.txt\t1000\t\t\t8192\t1\n"
940                                   "preselected.txt\tpreselected\tpreselected.txt\t1000\t\t\t8192\t2\n"
941                                   "notpreselected.txt\tnotpreselected\tnotpreselected.txt\t1000\t\t\t8192\t3\n";
942 
943 static const CHAR fo_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
944                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
945                                      "Feature\tFeature\n"
946                                      "override\t\t\toverride feature\t1\t1\tMSITESTDIR\t0\n"
947                                      "preselected\t\t\tpreselected feature\t1\t1\tMSITESTDIR\t0\n"
948                                      "notpreselected\t\t\tnotpreselected feature\t1\t1\tMSITESTDIR\t0\n";
949 
950 static const CHAR fo_condition_dat[] = "Feature_\tLevel\tCondition\n"
951                                        "s38\ti2\tS255\n"
952                                        "Condition\tFeature_\tLevel\n"
953                                        "preselected\t0\tPreselected AND NOT REMOVE\n"
954                                        "notpreselected\t0\tNOT Preselected AND NOT REMOVE\n";
955 
956 static const CHAR fo_feature_comp_dat[] = "Feature_\tComponent_\n"
957                                           "s38\ts72\n"
958                                           "FeatureComponents\tFeature_\tComponent_\n"
959                                           "override\toverride\n"
960                                           "preselected\tpreselected\n"
961                                           "notpreselected\tnotpreselected\n";
962 
963 static const CHAR fo_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
964                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
965                                        "Component\tComponent\n"
966                                        "override\t{0A00FB1D-97B0-4B42-ADF0-BB8913416623}\tMSITESTDIR\t0\t\toverride.txt\n"
967                                        "preselected\t{44E1DB75-605A-43DD-8CF5-CAB17F1BBD60}\tMSITESTDIR\t0\t\tpreselected.txt\n"
968                                        "notpreselected\t{E1647733-5E75-400A-A92E-5E60B4D4EF9F}\tMSITESTDIR\t0\t\tnotpreselected.txt\n";
969 
970 static const CHAR fo_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
971                                            "s72\ti2\tS64\tS0\tS255\n"
972                                            "CustomAction\tAction\n"
973                                            "SetPreselected\t51\tPreselected\t1\t\n";
974 
975 static const CHAR fo_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
976                                               "s72\tS255\tI2\n"
977                                               "InstallExecuteSequence\tAction\n"
978                                               "LaunchConditions\t\t100\n"
979                                               "SetPreselected\tpreselect=1\t200\n"
980                                               "CostInitialize\t\t800\n"
981                                               "FileCost\t\t900\n"
982                                               "CostFinalize\t\t1000\n"
983                                               "InstallValidate\t\t1400\n"
984                                               "InstallInitialize\t\t1500\n"
985                                               "ProcessComponents\t\t1600\n"
986                                               "RemoveFiles\t\t1700\n"
987                                               "InstallFiles\t\t2000\n"
988                                               "RegisterProduct\t\t5000\n"
989                                               "PublishFeatures\t\t5100\n"
990                                               "PublishProduct\t\t5200\n"
991                                               "UnpublishFeatures\t\t5300\n"
992                                               "InstallFinalize\t\t6000\n";
993 
994 static const CHAR uc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
995                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
996                                   "File\tFile\n"
997                                   "upgradecode.txt\tupgradecode\tupgradecode.txt\t1000\t\t\t8192\t1\n";
998 
999 static const CHAR uc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1000                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1001                                      "Feature\tFeature\n"
1002                                      "upgradecode\t\t\tupgradecode feature\t1\t2\tMSITESTDIR\t0\n";
1003 
1004 static const CHAR uc_feature_comp_dat[] = "Feature_\tComponent_\n"
1005                                           "s38\ts72\n"
1006                                           "FeatureComponents\tFeature_\tComponent_\n"
1007                                           "upgradecode\tupgradecode\n";
1008 
1009 static const CHAR uc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1010                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1011                                        "Component\tComponent\n"
1012                                        "upgradecode\t{6952B732-2FCB-4E47-976F-989FCBD7EDFB}\tMSITESTDIR\t0\t\tupgradecode.txt\n";
1013 
1014 static const CHAR uc_property_dat[] = "Property\tValue\n"
1015                                       "s72\tl0\n"
1016                                       "Property\tProperty\n"
1017                                       "INSTALLLEVEL\t3\n"
1018                                       "ProductCode\t{E5FB1241-F547-4BA7-A60E-8E75797268D4}\n"
1019                                       "ProductName\tMSITEST\n"
1020                                       "ProductVersion\t1.1.1\n"
1021                                       "UpgradeCode\t#UPGEADECODE#\n"
1022                                       "MSIFASTINSTALL\t1\n";
1023 
1024 static const CHAR uc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1025                                               "s72\tS255\tI2\n"
1026                                               "InstallExecuteSequence\tAction\n"
1027                                               "LaunchConditions\t\t100\n"
1028                                               "CostInitialize\t\t200\n"
1029                                               "FileCost\t\t300\n"
1030                                               "CostFinalize\t\t400\n"
1031                                               "InstallInitialize\t\t500\n"
1032                                               "ProcessComponents\t\t600\n"
1033                                               "InstallValidate\t\t700\n"
1034                                               "RemoveFiles\t\t800\n"
1035                                               "InstallFiles\t\t900\n"
1036                                               "RegisterProduct\t\t1000\n"
1037                                               "PublishFeatures\t\t1100\n"
1038                                               "PublishProduct\t\t1200\n"
1039                                               "UnpublishFeatures\t\t1250\n"
1040                                               "InstallFinalize\t\t1300\n";
1041 
1042 static const char mixed_feature_dat[] =
1043     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1044     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1045     "Feature\tFeature\n"
1046     "feature1\t\t\t\t1\t2\tMSITESTDIR\t0\n"
1047     "feature2\t\t\t\t1\t2\tMSITESTDIR\t0\n";
1048 
1049 static const char mixed_feature_comp_dat[] =
1050     "Feature_\tComponent_\n"
1051     "s38\ts72\n"
1052     "FeatureComponents\tFeature_\tComponent_\n"
1053     "feature1\tcomp1\n"
1054     "feature2\tcomp2\n";
1055 
1056 static const char mixed_component_dat[] =
1057     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1058     "s72\tS38\ts72\ti2\tS255\tS72\n"
1059     "Component\tComponent\n"
1060     "comp1\t{DE9F0EF4-0ED3-495A-8105-060C0EA457B8}\tTARGETDIR\t4\t\tregdata1\n"
1061     "comp2\t{4912DBE7-FC3A-4F91-BB5C-88F5C15C19A5}\tTARGETDIR\t260\t\tregdata2\n";
1062 
1063 static const char mixed_registry_dat[] =
1064     "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
1065     "s72\ti2\tl255\tL255\tL0\ts72\n"
1066     "Registry\tRegistry\n"
1067     "regdata1\t2\tSOFTWARE\\Wine\\msitest\ttest1\t\tcomp1\n"
1068     "regdata2\t2\tSOFTWARE\\Wine\\msitest\ttest2\t\tcomp2\n"
1069     "regdata3\t0\tCLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\t\tCLSID_Winetest32\tcomp1\n"
1070     "regdata4\t0\tCLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32\t\twinetest32.dll\tcomp1\n"
1071     "regdata5\t0\tCLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\t\tCLSID_Winetest64\tcomp2\n"
1072     "regdata6\t0\tCLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32\t\twinetest64.dll\tcomp2\n";
1073 
1074 static const char mixed_install_exec_seq_dat[] =
1075     "Action\tCondition\tSequence\n"
1076     "s72\tS255\tI2\n"
1077     "InstallExecuteSequence\tAction\n"
1078     "LaunchConditions\t\t100\n"
1079     "CostInitialize\t\t200\n"
1080     "FileCost\t\t300\n"
1081     "CostFinalize\t\t400\n"
1082     "InstallValidate\t\t500\n"
1083     "InstallInitialize\t\t600\n"
1084     "ProcessComponents\t\t700\n"
1085     "UnpublishFeatures\t\t800\n"
1086     "RemoveRegistryValues\t\t900\n"
1087     "WriteRegistryValues\t\t1000\n"
1088     "RegisterProduct\t\t1100\n"
1089     "PublishFeatures\t\t1200\n"
1090     "PublishProduct\t\t1300\n"
1091     "InstallFinalize\t\t1400\n";
1092 
1093 static const char vp_file_dat[] =
1094     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1095     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1096     "File\tFile\n"
1097     "volumeprop\tcomp\tvolumeprop.txt\t1000\t\t\t8192\t1\n";
1098 
1099 static const char vp_feature_dat[] =
1100     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1101     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1102     "Feature\tFeature\n"
1103     "feature\t\t\t\t1\t2\tMSITESTDIR\t0\n";
1104 
1105 static const char vp_feature_comp_dat[] =
1106     "Feature_\tComponent_\n"
1107     "s38\ts72\n"
1108     "FeatureComponents\tFeature_\tComponent_\n"
1109     "feature\tcomp\n";
1110 
1111 static const char vp_component_dat[] =
1112     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1113     "s72\tS38\ts72\ti2\tS255\tS72\n"
1114     "Component\tComponent\n"
1115     "comp\t{24364AE7-5B7F-496C-AF5A-54893639C567}\tMSITESTDIR\t0\t\tvolumeprop\n";
1116 
1117 static const char vp_custom_action_dat[] =
1118     "Action\tType\tSource\tTarget\tISComments\n"
1119     "s72\ti2\tS64\tS0\tS255\n"
1120     "CustomAction\tAction\n"
1121     "TestPrimaryVolumePath0\t19\t\tPrimaryVolumePath set before CostFinalize\t\n"
1122     "TestPrimaryVolumeSpaceAvailable0\t19\t\tPrimaryVolumeSpaceAvailable set before CostFinalize\t\n"
1123     "TestPrimaryVolumeSpaceRequired0\t19\t\tPrimaryVolumeSpaceRequired set before CostFinalize\t\n"
1124     "TestPrimaryVolumeSpaceRemaining0\t19\t\tPrimaryVolumeSpaceRemaining set before CostFinalize\t\n"
1125     "TestPrimaryVolumePath1\t19\t\tPrimaryVolumePath set before InstallValidate\t\n"
1126     "TestPrimaryVolumeSpaceAvailable1\t19\t\tPrimaryVolumeSpaceAvailable not set before InstallValidate\t\n"
1127     "TestPrimaryVolumeSpaceRequired1\t19\t\tPrimaryVolumeSpaceRequired not set before InstallValidate\t\n"
1128     "TestPrimaryVolumeSpaceRemaining1\t19\t\tPrimaryVolumeSpaceRemaining not set before InstallValidate\t\n"
1129     "TestPrimaryVolumePath2\t19\t\tPrimaryVolumePath not set after InstallValidate\t\n"
1130     "TestPrimaryVolumeSpaceAvailable2\t19\t\tPrimaryVolumeSpaceAvailable not set after InstallValidate\t\n"
1131     "TestPrimaryVolumeSpaceRequired2\t19\t\tPrimaryVolumeSpaceRequired not set after InstallValidate\t\n"
1132     "TestPrimaryVolumeSpaceRemaining2\t19\t\tPrimaryVolumeSpaceRemaining not set after InstallValidate\t\n";
1133 
1134 static const char vp_install_exec_seq_dat[] =
1135     "Action\tCondition\tSequence\n"
1136     "s72\tS255\tI2\n"
1137     "InstallExecuteSequence\tAction\n"
1138     "LaunchConditions\t\t100\n"
1139     "CostInitialize\t\t200\n"
1140     "FileCost\t\t300\n"
1141     "TestPrimaryVolumePath0\tPrimaryVolumePath AND NOT REMOVE\t400\n"
1142     "TestPrimaryVolumeSpaceAvailable0\tPrimaryVolumeSpaceAvailable AND NOT REMOVE\t500\n"
1143     "TestPrimaryVolumeSpaceRequired0\tPrimaryVolumeSpaceRequired AND NOT REMOVE\t510\n"
1144     "TestPrimaryVolumeSpaceRemaining0\tPrimaryVolumeSpaceRemaining AND NOT REMOVE\t520\n"
1145     "CostFinalize\t\t600\n"
1146     "TestPrimaryVolumePath1\tPrimaryVolumePath AND NOT REMOVE\t600\n"
1147     "TestPrimaryVolumeSpaceAvailable1\tNOT PrimaryVolumeSpaceAvailable AND NOT REMOVE\t800\n"
1148     "TestPrimaryVolumeSpaceRequired1\tNOT PrimaryVolumeSpaceRequired AND NOT REMOVE\t810\n"
1149     "TestPrimaryVolumeSpaceRemaining1\tNOT PrimaryVolumeSpaceRemaining AND NOT REMOVE\t820\n"
1150     "InstallValidate\t\t900\n"
1151     "TestPrimaryVolumePath2\tNOT PrimaryVolumePath AND NOT REMOVE\t1000\n"
1152     "TestPrimaryVolumeSpaceAvailable2\tNOT PrimaryVolumeSpaceAvailable AND NOT REMOVE\t1100\n"
1153     "TestPrimaryVolumeSpaceRequired2\tNOT PrimaryVolumeSpaceRequired AND NOT REMOVE\t1110\n"
1154     "TestPrimaryVolumeSpaceRemaining2\tNOT PrimaryVolumeSpaceRemaining AND NOT REMOVE\t1120\n"
1155     "InstallInitialize\t\t1200\n"
1156     "ProcessComponents\t\t1300\n"
1157     "RemoveFiles\t\t1400\n"
1158     "InstallFiles\t\t1500\n"
1159     "RegisterProduct\t\t1600\n"
1160     "PublishFeatures\t\t1700\n"
1161     "PublishProduct\t\t1800\n"
1162     "UnpublishFeatures\t\t1850\n"
1163     "InstallFinalize\t\t1900\n";
1164 
1165 static const char shc_property_dat[] =
1166     "Property\tValue\n"
1167     "s72\tl0\n"
1168     "Property\tProperty\n"
1169     "INSTALLLEVEL\t3\n"
1170     "ProductCode\t{5CD99CD0-69C7-409B-9905-82DD743CC840}\n"
1171     "ProductName\tMSITEST\n"
1172     "ProductVersion\t1.1.1\n"
1173     "MSIFASTINSTALL\t1\n";
1174 
1175 static const char shc2_property_dat[] =
1176     "Property\tValue\n"
1177     "s72\tl0\n"
1178     "Property\tProperty\n"
1179     "INSTALLLEVEL\t3\n"
1180     "ProductCode\t{4CEFADE5-DAFB-4C21-8EF2-4ED4F139F340}\n"
1181     "ProductName\tMSITEST2\n"
1182     "ProductVersion\t1.1.1\n"
1183     "MSIFASTINSTALL\t1\n";
1184 
1185 static const char shc_file_dat[] =
1186     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1187     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1188     "File\tFile\n"
1189     "sharedcomponent\tsharedcomponent\tsharedcomponent.txt\t1000\t\t\t8192\t1\n";
1190 
1191 static const char shc_feature_dat[] =
1192     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1193     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1194     "Feature\tFeature\n"
1195     "feature\t\t\t\t1\t2\tMSITESTDIR\t0\n";
1196 
1197 static const char shc_feature_comp_dat[] =
1198     "Feature_\tComponent_\n"
1199     "s38\ts72\n"
1200     "FeatureComponents\tFeature_\tComponent_\n"
1201     "feature\tsharedcomponent\n";
1202 
1203 static const char shc_component_dat[] =
1204     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1205     "s72\tS38\ts72\ti2\tS255\tS72\n"
1206     "Component\tComponent\n"
1207     "sharedcomponent\t{900A4ACB-DC6F-4795-A04B-81B530183D41}\tMSITESTDIR\t0\t\tsharedcomponent\n";
1208 
1209 static const char shc_custom_action_dat[] =
1210     "Action\tType\tSource\tTarget\tISComments\n"
1211     "s72\ti2\tS64\tS0\tS255\n"
1212     "CustomAction\tAction\n"
1213     "TestComponentAction\t19\t\twrong component action on install\t\n"
1214     "TestDisallowedAction\t19\t\twrong component action on disallowed remove\t\n"
1215     "TestRemoveAction\t19\t\twrong component action on remove\t\n";
1216 
1217 static const char shc_install_exec_seq_dat[] =
1218     "Action\tCondition\tSequence\n"
1219     "s72\tS255\tI2\n"
1220     "InstallExecuteSequence\tAction\n"
1221     "LaunchConditions\t\t100\n"
1222     "CostInitialize\t\t200\n"
1223     "FileCost\t\t300\n"
1224     "CostFinalize\t\t600\n"
1225     "TestDisallowedAction\tREMOVE AND ($sharedcomponent <> -1)\t700\n"
1226     "InstallValidate\t\t900\n"
1227     "InstallInitialize\t\t1200\n"
1228     "ProcessComponents\t\t1300\n"
1229     "RemoveFiles\t\t1400\n"
1230     "InstallFiles\t\t1500\n"
1231     "TestComponentAction\tNOT REMOVE AND ($sharedcomponent <> 3)\t1600\n"
1232     "RegisterProduct\t\t1700\n"
1233     "PublishFeatures\t\t1800\n"
1234     "PublishProduct\t\t1900\n"
1235     "UnpublishFeatures\t\t1950\n"
1236     "InstallFinalize\t\t2000\n";
1237 
1238 static const char shc2_install_exec_seq_dat[] =
1239     "Action\tCondition\tSequence\n"
1240     "s72\tS255\tI2\n"
1241     "InstallExecuteSequence\tAction\n"
1242     "LaunchConditions\t\t100\n"
1243     "CostInitialize\t\t200\n"
1244     "FileCost\t\t300\n"
1245     "CostFinalize\t\t600\n"
1246     "TestRemoveAction\tREMOVE AND ($sharedcomponent <> 2)\t700\n"
1247     "InstallValidate\t\t900\n"
1248     "InstallInitialize\t\t1200\n"
1249     "ProcessComponents\t\t1300\n"
1250     "RemoveFiles\t\t1400\n"
1251     "InstallFiles\t\t1500\n"
1252     "TestComponentAction\tNOT REMOVE AND ($sharedcomponent <> 3)\t1600\n"
1253     "RegisterProduct\t\t1700\n"
1254     "PublishFeatures\t\t1800\n"
1255     "PublishProduct\t\t1900\n"
1256     "UnpublishFeatures\t\t1950\n"
1257     "InstallFinalize\t\t2000\n";
1258 
1259 static const char ft_file_dat[] =
1260     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1261     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1262     "File\tFile\n"
1263     "featuretree\tcomp\tfeaturetree.txt\t1000\t\t\t8192\t1\n";
1264 
1265 static const char ft_comp_dat[] =
1266     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1267     "s72\tS38\ts72\ti2\tS255\tS72\n"
1268     "Component\tComponent\n"
1269     "comp\t{12345678-1234-1234-1234-222222222222}\tTARGETDIR\t0\t\t\n"
1270     "comp2\t{12345678-1234-1234-1234-333333333333}\tTARGETDIR\t0\t\tfeaturetree\n";
1271 
1272 static const char ft_feature_dat[] =
1273     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1274     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1275     "Feature\tFeature\n"
1276     "A\t\t\t\t2\t1\t\t0\n"
1277     "C\tB\t\t\t2\t1\t\t0\n"
1278     "B\tA\t\t\t4\t1\t\t0\n"
1279     "D\t\t\t\t2\t1\t\t0\n";
1280 
1281 static const char ft_feature_comp_dat[] =
1282     "Feature_\tComponent_\n"
1283     "s38\ts72\n"
1284     "FeatureComponents\tFeature_\tComponent_\n"
1285     "C\tcomp\n"
1286     "D\tcomp2\n";
1287 
1288 static const char ft_condition_dat[] =
1289     "Feature_\tLevel\tCondition\n"
1290     "s38\ti2\tS255\n"
1291     "Condition\tFeature_\tLevel\n"
1292     "A\t0\t\"0\"<>INSTALLTYPE\n";
1293 
1294 static const char ft_custom_action_dat[] =
1295     "Action\tType\tSource\tTarget\tISComments\n"
1296     "s72\ti2\tS64\tS0\tS255\n"
1297     "CustomAction\tAction\n"
1298     "Run A\t19\t\tA\t\n"
1299     "Run B\t19\t\tB\t\n"
1300     "Run C\t19\t\tC\t\n";
1301 
1302 static const char ft_install_exec_seq_dat[] =
1303     "Action\tCondition\tSequence\n"
1304     "s72\tS255\tI2\n"
1305     "InstallExecuteSequence\tAction\n"
1306     "CostInitialize\t\t100\n"
1307     "FileCost\t\t200\n"
1308     "CostFinalize\t\t300\n"
1309     "InstallValidate\t\t400\n"
1310     "InstallInitialize\t\t500\n"
1311     "Run C\t3 = &C AND NOT Installed\t600\n"
1312     "Run B\t3 = &B AND NOT Installed\t700\n"
1313     "Run A\t3 = &A AND NOT Installed\t800\n"
1314     "ProcessComponents\t\t900\n"
1315     "RemoveFiles\t\t1000\n"
1316     "InstallFiles\t\t1100\n"
1317     "RegisterProduct\t\t1200\n"
1318     "PublishFeatures\t\t1300\n"
1319     "PublishProduct\t\t1400\n"
1320     "UnpublishFeatures\t\t1450\n"
1321     "InstallFinalize\t\t1500\n";
1322 
1323 static const char da_custom_action_dat[] =
1324     "Action\tType\tSource\tTarget\n"
1325     "s72\ti2\tS64\tS0\n"
1326     "CustomAction\tAction\n"
1327     "setprop\t51\tdeferred\t[TESTPATH]\n"
1328     "immediate\t1\tcustom.dll\tda_immediate\n"
1329     "deferred\t1025\tcustom.dll\tda_deferred\n";
1330 
1331 static const char da_install_exec_seq_dat[] =
1332     "Action\tCondition\tSequence\n"
1333     "s72\tS255\tI2\n"
1334     "InstallExecuteSequence\tAction\n"
1335     "CostInitialize\t\t200\n"
1336     "FileCost\t\t300\n"
1337     "CostFinalize\t\t400\n"
1338     "InstallInitialize\t\t500\n"
1339     "setprop\t\t600\n"
1340     "deferred\t\t700\n"
1341     "immediate\t\t800\n"
1342     "InstallFinalize\t\t1100\n";
1343 
1344 static const CHAR x64_directory_dat[] =
1345     "Directory\tDirectory_Parent\tDefaultDir\n"
1346     "s72\tS72\tl255\n"
1347     "Directory\tDirectory\n"
1348     "CABOUTDIR\tMSITESTDIR\tcabout\n"
1349     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
1350     "FIRSTDIR\tMSITESTDIR\tfirst\n"
1351     "MSITESTDIR\tProgramFiles64Folder\tmsitest\n"
1352     "NEWDIR\tCABOUTDIR\tnew\n"
1353     "ProgramFiles64Folder\tTARGETDIR\t.\n"
1354     "TARGETDIR\t\tSourceDir";
1355 
1356 static const CHAR sr_install_exec_seq_dat[] =
1357     "Action\tCondition\tSequence\n"
1358     "s72\tS255\tI2\n"
1359     "InstallExecuteSequence\tAction\n"
1360     "CostInitialize\t\t200\n"
1361     "FileCost\t\t300\n"
1362     "CostFinalize\t\t400\n"
1363     "InstallValidate\t\t500\n"
1364     "InstallInitialize\t\t600\n"
1365     "sourcedir_unset\tSourceDir\t700\n"
1366     "ResolveSource\tRESOLVE_SOURCE\t800\n"
1367     "ProcessComponents\tPROCESS_COMPONENTS\t800\n"
1368     "InstallFiles\tINSTALL_FILES\t800\n"
1369     "sourcedir_set\tNOT SourceDir\t900\n"
1370     "InstallFinalize\t\t1000\n";
1371 
1372 static const CHAR sr_custom_action_dat[] =
1373     "Action\tType\tSource\tTarget\n"
1374     "s72\ti2\tS64\tS0\n"
1375     "CustomAction\tAction\n"
1376     "sourcedir_unset\t19\t\tSourceDir should not be set\n"
1377     "sourcedir_set\t19\t\tSourceDir should be set\n";
1378 
1379 static const CHAR ai2_file_dat[] =
1380     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1381     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1382     "File\tFile\n"
1383     "five.txt\tFive\tfive.txt\t1000\t\t\t0\t5\n"
1384     "four.txt\tFour\tfour.txt\t1000\t\t\t0\t4\n";
1385 
1386 static const CHAR ai2_component_dat[] =
1387     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1388     "s72\tS38\ts72\ti2\tS255\tS72\n"
1389     "Component\tComponent\n"
1390     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
1391     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n";
1392 
1393 static const CHAR ai2_feature_dat[] =
1394     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1395     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1396     "Feature\tFeature\n"
1397     "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
1398     "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n";
1399 
1400 static const CHAR ai2_feature_comp_dat[] =
1401     "Feature_\tComponent_\n"
1402     "s38\ts72\n"
1403     "FeatureComponents\tFeature_\tComponent_\n"
1404     "Five\tFive\n"
1405     "Four\tFour\n";
1406 
1407 static const msi_table tables[] =
1408 {
1409     ADD_TABLE(component),
1410     ADD_TABLE(directory),
1411     ADD_TABLE(feature),
1412     ADD_TABLE(feature_comp),
1413     ADD_TABLE(file),
1414     ADD_TABLE(install_exec_seq),
1415     ADD_TABLE(media),
1416     ADD_TABLE(property),
1417     ADD_TABLE(registry),
1418 };
1419 
1420 static const msi_table sc_tables[] =
1421 {
1422     ADD_TABLE(component),
1423     ADD_TABLE(directory),
1424     ADD_TABLE(feature),
1425     ADD_TABLE(feature_comp),
1426     ADD_TABLE(file),
1427     ADD_TABLE(install_exec_seq),
1428     ADD_TABLE(media),
1429     ADD_TABLE(property),
1430     ADD_TABLE(shortcut)
1431 };
1432 
1433 static const msi_table ps_tables[] =
1434 {
1435     ADD_TABLE(component),
1436     ADD_TABLE(directory),
1437     ADD_TABLE(feature),
1438     ADD_TABLE(feature_comp),
1439     ADD_TABLE(file),
1440     ADD_TABLE(install_exec_seq),
1441     ADD_TABLE(media),
1442     ADD_TABLE(property),
1443     ADD_TABLE(condition)
1444 };
1445 
1446 static const msi_table up_tables[] =
1447 {
1448     ADD_TABLE(component),
1449     ADD_TABLE(directory),
1450     ADD_TABLE(feature),
1451     ADD_TABLE(feature_comp),
1452     ADD_TABLE(file),
1453     ADD_TABLE(install_exec_seq),
1454     ADD_TABLE(media),
1455     ADD_TABLE(up_property),
1456     ADD_TABLE(registry),
1457 };
1458 
1459 static const msi_table up2_tables[] =
1460 {
1461     ADD_TABLE(component),
1462     ADD_TABLE(directory),
1463     ADD_TABLE(feature),
1464     ADD_TABLE(feature_comp),
1465     ADD_TABLE(file),
1466     ADD_TABLE(install_exec_seq),
1467     ADD_TABLE(media),
1468     ADD_TABLE(up2_property),
1469     ADD_TABLE(registry),
1470 };
1471 
1472 static const msi_table up3_tables[] =
1473 {
1474     ADD_TABLE(component),
1475     ADD_TABLE(directory),
1476     ADD_TABLE(feature),
1477     ADD_TABLE(feature_comp),
1478     ADD_TABLE(file),
1479     ADD_TABLE(install_exec_seq),
1480     ADD_TABLE(media),
1481     ADD_TABLE(up3_property),
1482     ADD_TABLE(registry),
1483 };
1484 
1485 static const msi_table up4_tables[] =
1486 {
1487     ADD_TABLE(component),
1488     ADD_TABLE(directory),
1489     ADD_TABLE(feature),
1490     ADD_TABLE(feature_comp),
1491     ADD_TABLE(file),
1492     ADD_TABLE(pp_install_exec_seq),
1493     ADD_TABLE(media),
1494     ADD_TABLE(property),
1495     ADD_TABLE(registry),
1496 };
1497 
1498 static const msi_table up5_tables[] =
1499 {
1500     ADD_TABLE(component),
1501     ADD_TABLE(directory),
1502     ADD_TABLE(feature),
1503     ADD_TABLE(feature_comp),
1504     ADD_TABLE(file),
1505     ADD_TABLE(pp_install_exec_seq),
1506     ADD_TABLE(media),
1507     ADD_TABLE(up_property),
1508     ADD_TABLE(registry),
1509 };
1510 
1511 static const msi_table up6_tables[] =
1512 {
1513     ADD_TABLE(component),
1514     ADD_TABLE(directory),
1515     ADD_TABLE(feature),
1516     ADD_TABLE(feature_comp),
1517     ADD_TABLE(file),
1518     ADD_TABLE(pp_install_exec_seq),
1519     ADD_TABLE(media),
1520     ADD_TABLE(up2_property),
1521     ADD_TABLE(registry),
1522 };
1523 
1524 static const msi_table up7_tables[] =
1525 {
1526     ADD_TABLE(component),
1527     ADD_TABLE(directory),
1528     ADD_TABLE(feature),
1529     ADD_TABLE(feature_comp),
1530     ADD_TABLE(file),
1531     ADD_TABLE(pp_install_exec_seq),
1532     ADD_TABLE(media),
1533     ADD_TABLE(up3_property),
1534     ADD_TABLE(registry),
1535 };
1536 
1537 static const msi_table cc_tables[] =
1538 {
1539     ADD_TABLE(cc_component),
1540     ADD_TABLE(directory),
1541     ADD_TABLE(cc_feature),
1542     ADD_TABLE(cc_feature_comp),
1543     ADD_TABLE(cc_file),
1544     ADD_TABLE(install_exec_seq),
1545     ADD_TABLE(cc_media),
1546     ADD_TABLE(property),
1547 };
1548 
1549 static const msi_table cc2_tables[] =
1550 {
1551     ADD_TABLE(cc2_component),
1552     ADD_TABLE(directory),
1553     ADD_TABLE(cc_feature),
1554     ADD_TABLE(cc_feature_comp),
1555     ADD_TABLE(cc2_file),
1556     ADD_TABLE(install_exec_seq),
1557     ADD_TABLE(cc_media),
1558     ADD_TABLE(property),
1559 };
1560 
1561 static const msi_table cc3_tables[] =
1562 {
1563     ADD_TABLE(cc_component),
1564     ADD_TABLE(directory),
1565     ADD_TABLE(cc_feature),
1566     ADD_TABLE(cc_feature_comp),
1567     ADD_TABLE(cc_file),
1568     ADD_TABLE(install_exec_seq),
1569     ADD_TABLE(cc3_media),
1570     ADD_TABLE(property),
1571 };
1572 
1573 static const msi_table co_tables[] =
1574 {
1575     ADD_TABLE(cc_component),
1576     ADD_TABLE(directory),
1577     ADD_TABLE(cc_feature),
1578     ADD_TABLE(cc_feature_comp),
1579     ADD_TABLE(co_file),
1580     ADD_TABLE(install_exec_seq),
1581     ADD_TABLE(co_media),
1582     ADD_TABLE(property),
1583 };
1584 
1585 static const msi_table co2_tables[] =
1586 {
1587     ADD_TABLE(cc_component),
1588     ADD_TABLE(directory),
1589     ADD_TABLE(cc_feature),
1590     ADD_TABLE(cc_feature_comp),
1591     ADD_TABLE(cc_file),
1592     ADD_TABLE(install_exec_seq),
1593     ADD_TABLE(co2_media),
1594     ADD_TABLE(property),
1595 };
1596 
1597 static const msi_table mm_tables[] =
1598 {
1599     ADD_TABLE(cc_component),
1600     ADD_TABLE(directory),
1601     ADD_TABLE(cc_feature),
1602     ADD_TABLE(cc_feature_comp),
1603     ADD_TABLE(mm_file),
1604     ADD_TABLE(install_exec_seq),
1605     ADD_TABLE(mm_media),
1606     ADD_TABLE(property),
1607 };
1608 
1609 static const msi_table ss_tables[] =
1610 {
1611     ADD_TABLE(cc_component),
1612     ADD_TABLE(directory),
1613     ADD_TABLE(cc_feature),
1614     ADD_TABLE(cc_feature_comp),
1615     ADD_TABLE(cc_file),
1616     ADD_TABLE(install_exec_seq),
1617     ADD_TABLE(ss_media),
1618     ADD_TABLE(property),
1619 };
1620 
1621 static const msi_table ui_tables[] =
1622 {
1623     ADD_TABLE(ui_component),
1624     ADD_TABLE(directory),
1625     ADD_TABLE(cc_feature),
1626     ADD_TABLE(cc_feature_comp),
1627     ADD_TABLE(cc_file),
1628     ADD_TABLE(install_exec_seq),
1629     ADD_TABLE(ui_install_ui_seq),
1630     ADD_TABLE(ui_custom_action),
1631     ADD_TABLE(cc_media),
1632     ADD_TABLE(property),
1633 };
1634 
1635 static const msi_table rof_tables[] =
1636 {
1637     ADD_TABLE(rof_component),
1638     ADD_TABLE(directory),
1639     ADD_TABLE(rof_feature),
1640     ADD_TABLE(rof_feature_comp),
1641     ADD_TABLE(rof_file),
1642     ADD_TABLE(install_exec_seq),
1643     ADD_TABLE(rof_media),
1644     ADD_TABLE(property),
1645 };
1646 
1647 static const msi_table rofc_tables[] =
1648 {
1649     ADD_TABLE(rof_component),
1650     ADD_TABLE(directory),
1651     ADD_TABLE(rof_feature),
1652     ADD_TABLE(rof_feature_comp),
1653     ADD_TABLE(rofc_file),
1654     ADD_TABLE(install_exec_seq),
1655     ADD_TABLE(rofc_media),
1656     ADD_TABLE(property),
1657 };
1658 
1659 static const msi_table sdp_tables[] =
1660 {
1661     ADD_TABLE(rof_component),
1662     ADD_TABLE(directory),
1663     ADD_TABLE(rof_feature),
1664     ADD_TABLE(rof_feature_comp),
1665     ADD_TABLE(rof_file),
1666     ADD_TABLE(sdp_install_exec_seq),
1667     ADD_TABLE(sdp_custom_action),
1668     ADD_TABLE(rof_media),
1669     ADD_TABLE(property),
1670 };
1671 
1672 static const msi_table cie_tables[] =
1673 {
1674     ADD_TABLE(cie_component),
1675     ADD_TABLE(directory),
1676     ADD_TABLE(cc_feature),
1677     ADD_TABLE(cie_feature_comp),
1678     ADD_TABLE(cie_file),
1679     ADD_TABLE(install_exec_seq),
1680     ADD_TABLE(cie_media),
1681     ADD_TABLE(property),
1682 };
1683 
1684 static const msi_table tp_tables[] =
1685 {
1686     ADD_TABLE(tp_component),
1687     ADD_TABLE(directory),
1688     ADD_TABLE(rof_feature),
1689     ADD_TABLE(ci2_feature_comp),
1690     ADD_TABLE(ci2_file),
1691     ADD_TABLE(install_exec_seq),
1692     ADD_TABLE(rof_media),
1693     ADD_TABLE(property),
1694 };
1695 
1696 static const msi_table cwd_tables[] =
1697 {
1698     ADD_TABLE(cwd_component),
1699     ADD_TABLE(directory),
1700     ADD_TABLE(rof_feature),
1701     ADD_TABLE(ci2_feature_comp),
1702     ADD_TABLE(ci2_file),
1703     ADD_TABLE(install_exec_seq),
1704     ADD_TABLE(rof_media),
1705     ADD_TABLE(property),
1706 };
1707 
1708 static const msi_table adm_tables[] =
1709 {
1710     ADD_TABLE(adm_component),
1711     ADD_TABLE(directory),
1712     ADD_TABLE(rof_feature),
1713     ADD_TABLE(ci2_feature_comp),
1714     ADD_TABLE(ci2_file),
1715     ADD_TABLE(install_exec_seq),
1716     ADD_TABLE(rof_media),
1717     ADD_TABLE(property),
1718     ADD_TABLE(adm_custom_action),
1719     ADD_TABLE(adm_admin_exec_seq),
1720 };
1721 
1722 static const msi_table amp_tables[] =
1723 {
1724     ADD_TABLE(amp_component),
1725     ADD_TABLE(directory),
1726     ADD_TABLE(rof_feature),
1727     ADD_TABLE(ci2_feature_comp),
1728     ADD_TABLE(ci2_file),
1729     ADD_TABLE(install_exec_seq),
1730     ADD_TABLE(rof_media),
1731     ADD_TABLE(property),
1732 };
1733 
1734 static const msi_table mc_tables[] =
1735 {
1736     ADD_TABLE(mc_component),
1737     ADD_TABLE(directory),
1738     ADD_TABLE(cc_feature),
1739     ADD_TABLE(cie_feature_comp),
1740     ADD_TABLE(mc_file),
1741     ADD_TABLE(install_exec_seq),
1742     ADD_TABLE(mc_media),
1743     ADD_TABLE(property),
1744     ADD_TABLE(mc_file_hash),
1745 };
1746 
1747 static const msi_table sf_tables[] =
1748 {
1749     ADD_TABLE(wrv_component),
1750     ADD_TABLE(directory),
1751     ADD_TABLE(rof_feature),
1752     ADD_TABLE(ci2_feature_comp),
1753     ADD_TABLE(ci2_file),
1754     ADD_TABLE(install_exec_seq),
1755     ADD_TABLE(rof_media),
1756     ADD_TABLE(property),
1757 };
1758 
1759 static const msi_table ca1_tables[] =
1760 {
1761     ADD_TABLE(component),
1762     ADD_TABLE(directory),
1763     ADD_TABLE(feature),
1764     ADD_TABLE(feature_comp),
1765     ADD_TABLE(file),
1766     ADD_TABLE(property),
1767     ADD_TABLE(directory),
1768     ADD_TABLE(ca1_install_exec_seq),
1769     ADD_TABLE(ca1_custom_action),
1770     ADD_TABLE(ca1_test_seq),
1771     ADD_TABLE(ca1_test2),
1772     ADD_TABLE(ca1__validation),
1773 };
1774 
1775 static const msi_table ca51_tables[] =
1776 {
1777     ADD_TABLE(ca51_component),
1778     ADD_TABLE(directory),
1779     ADD_TABLE(rof_feature),
1780     ADD_TABLE(ci2_feature_comp),
1781     ADD_TABLE(ci2_file),
1782     ADD_TABLE(ca51_install_exec_seq),
1783     ADD_TABLE(rof_media),
1784     ADD_TABLE(property),
1785     ADD_TABLE(ca51_custom_action),
1786 };
1787 
1788 static const msi_table is_tables[] =
1789 {
1790     ADD_TABLE(is_component),
1791     ADD_TABLE(directory),
1792     ADD_TABLE(is_feature),
1793     ADD_TABLE(is_feature_comp),
1794     ADD_TABLE(is_file),
1795     ADD_TABLE(install_exec_seq),
1796     ADD_TABLE(is_media),
1797     ADD_TABLE(property),
1798 };
1799 
1800 static const msi_table sp_tables[] =
1801 {
1802     ADD_TABLE(sp_component),
1803     ADD_TABLE(sp_directory),
1804     ADD_TABLE(rof_feature),
1805     ADD_TABLE(ci2_feature_comp),
1806     ADD_TABLE(ci2_file),
1807     ADD_TABLE(install_exec_seq),
1808     ADD_TABLE(rof_media),
1809     ADD_TABLE(property),
1810 };
1811 
1812 static const msi_table mcp_tables[] =
1813 {
1814     ADD_TABLE(mcp_component),
1815     ADD_TABLE(directory),
1816     ADD_TABLE(mcp_feature),
1817     ADD_TABLE(mcp_feature_comp),
1818     ADD_TABLE(mcp_file),
1819     ADD_TABLE(rem_install_exec_seq),
1820     ADD_TABLE(rof_media),
1821     ADD_TABLE(property),
1822 };
1823 
1824 static const msi_table ai_tables[] =
1825 {
1826     ADD_TABLE(component),
1827     ADD_TABLE(directory),
1828     ADD_TABLE(feature),
1829     ADD_TABLE(feature_comp),
1830     ADD_TABLE(ai_file),
1831     ADD_TABLE(install_exec_seq),
1832     ADD_TABLE(media),
1833     ADD_TABLE(property)
1834 };
1835 
1836 static const msi_table ai2_tables[] =
1837 {
1838     ADD_TABLE(ai2_component),
1839     ADD_TABLE(directory),
1840     ADD_TABLE(ai2_feature),
1841     ADD_TABLE(ai2_feature_comp),
1842     ADD_TABLE(ai2_file),
1843     ADD_TABLE(install_exec_seq),
1844     ADD_TABLE(media),
1845     ADD_TABLE(property)
1846 };
1847 
1848 static const msi_table pc_tables[] =
1849 {
1850     ADD_TABLE(ca51_component),
1851     ADD_TABLE(directory),
1852     ADD_TABLE(rof_feature),
1853     ADD_TABLE(ci2_feature_comp),
1854     ADD_TABLE(ci2_file),
1855     ADD_TABLE(install_exec_seq),
1856     ADD_TABLE(rof_media),
1857     ADD_TABLE(property)
1858 };
1859 
1860 static const msi_table ip_tables[] =
1861 {
1862     ADD_TABLE(component),
1863     ADD_TABLE(directory),
1864     ADD_TABLE(feature),
1865     ADD_TABLE(feature_comp),
1866     ADD_TABLE(file),
1867     ADD_TABLE(ip_install_exec_seq),
1868     ADD_TABLE(ip_custom_action),
1869     ADD_TABLE(media),
1870     ADD_TABLE(property)
1871 };
1872 
1873 static const msi_table aup_tables[] =
1874 {
1875     ADD_TABLE(component),
1876     ADD_TABLE(directory),
1877     ADD_TABLE(feature),
1878     ADD_TABLE(feature_comp),
1879     ADD_TABLE(file),
1880     ADD_TABLE(aup_install_exec_seq),
1881     ADD_TABLE(aup_custom_action),
1882     ADD_TABLE(media),
1883     ADD_TABLE(property)
1884 };
1885 
1886 static const msi_table aup2_tables[] =
1887 {
1888     ADD_TABLE(component),
1889     ADD_TABLE(directory),
1890     ADD_TABLE(feature),
1891     ADD_TABLE(feature_comp),
1892     ADD_TABLE(file),
1893     ADD_TABLE(aup2_install_exec_seq),
1894     ADD_TABLE(aup_custom_action),
1895     ADD_TABLE(media),
1896     ADD_TABLE(aup_property)
1897 };
1898 
1899 static const msi_table aup3_tables[] =
1900 {
1901     ADD_TABLE(component),
1902     ADD_TABLE(directory),
1903     ADD_TABLE(feature),
1904     ADD_TABLE(feature_comp),
1905     ADD_TABLE(file),
1906     ADD_TABLE(aup2_install_exec_seq),
1907     ADD_TABLE(aup_custom_action),
1908     ADD_TABLE(media),
1909     ADD_TABLE(aup2_property)
1910 };
1911 
1912 static const msi_table aup4_tables[] =
1913 {
1914     ADD_TABLE(component),
1915     ADD_TABLE(directory),
1916     ADD_TABLE(feature),
1917     ADD_TABLE(feature_comp),
1918     ADD_TABLE(file),
1919     ADD_TABLE(aup3_install_exec_seq),
1920     ADD_TABLE(aup_custom_action),
1921     ADD_TABLE(media),
1922     ADD_TABLE(aup2_property)
1923 };
1924 
1925 static const msi_table fiu_tables[] =
1926 {
1927     ADD_TABLE(rof_component),
1928     ADD_TABLE(directory),
1929     ADD_TABLE(rof_feature),
1930     ADD_TABLE(rof_feature_comp),
1931     ADD_TABLE(rof_file),
1932     ADD_TABLE(pp_install_exec_seq),
1933     ADD_TABLE(rof_media),
1934     ADD_TABLE(property),
1935 };
1936 
1937 static const msi_table fiuc_tables[] =
1938 {
1939     ADD_TABLE(rof_component),
1940     ADD_TABLE(directory),
1941     ADD_TABLE(rof_feature),
1942     ADD_TABLE(rof_feature_comp),
1943     ADD_TABLE(rofc_file),
1944     ADD_TABLE(pp_install_exec_seq),
1945     ADD_TABLE(rofc_media),
1946     ADD_TABLE(property),
1947 };
1948 
1949 static const msi_table fo_tables[] =
1950 {
1951     ADD_TABLE(directory),
1952     ADD_TABLE(fo_file),
1953     ADD_TABLE(fo_component),
1954     ADD_TABLE(fo_feature),
1955     ADD_TABLE(fo_condition),
1956     ADD_TABLE(fo_feature_comp),
1957     ADD_TABLE(fo_custom_action),
1958     ADD_TABLE(fo_install_exec_seq),
1959     ADD_TABLE(media),
1960     ADD_TABLE(property)
1961 };
1962 
1963 static const msi_table icon_base_tables[] =
1964 {
1965     ADD_TABLE(ci_component),
1966     ADD_TABLE(directory),
1967     ADD_TABLE(rof_feature),
1968     ADD_TABLE(rof_feature_comp),
1969     ADD_TABLE(rof_file),
1970     ADD_TABLE(pp_install_exec_seq),
1971     ADD_TABLE(rof_media),
1972     ADD_TABLE(icon_property),
1973 };
1974 
1975 static const msi_table pv_tables[] =
1976 {
1977     ADD_TABLE(rof_component),
1978     ADD_TABLE(directory),
1979     ADD_TABLE(rof_feature),
1980     ADD_TABLE(rof_feature_comp),
1981     ADD_TABLE(rof_file),
1982     ADD_TABLE(pv_install_exec_seq),
1983     ADD_TABLE(rof_media),
1984     ADD_TABLE(property)
1985 };
1986 
1987 static const msi_table uc_tables[] =
1988 {
1989     ADD_TABLE(directory),
1990     ADD_TABLE(uc_component),
1991     ADD_TABLE(uc_feature),
1992     ADD_TABLE(uc_feature_comp),
1993     ADD_TABLE(uc_file),
1994     ADD_TABLE(uc_install_exec_seq),
1995     ADD_TABLE(media),
1996     ADD_TABLE(uc_property)
1997 };
1998 
1999 static const msi_table mixed_tables[] =
2000 {
2001     ADD_TABLE(directory),
2002     ADD_TABLE(mixed_component),
2003     ADD_TABLE(mixed_feature),
2004     ADD_TABLE(mixed_feature_comp),
2005     ADD_TABLE(mixed_install_exec_seq),
2006     ADD_TABLE(mixed_registry),
2007     ADD_TABLE(media),
2008     ADD_TABLE(property)
2009 };
2010 
2011 static const msi_table vp_tables[] =
2012 {
2013     ADD_TABLE(directory),
2014     ADD_TABLE(vp_file),
2015     ADD_TABLE(vp_component),
2016     ADD_TABLE(vp_feature),
2017     ADD_TABLE(vp_feature_comp),
2018     ADD_TABLE(vp_custom_action),
2019     ADD_TABLE(vp_install_exec_seq),
2020     ADD_TABLE(media),
2021     ADD_TABLE(property)
2022 };
2023 
2024 static const msi_table shc_tables[] =
2025 {
2026     ADD_TABLE(media),
2027     ADD_TABLE(directory),
2028     ADD_TABLE(shc_file),
2029     ADD_TABLE(shc_component),
2030     ADD_TABLE(shc_feature),
2031     ADD_TABLE(shc_feature_comp),
2032     ADD_TABLE(shc_custom_action),
2033     ADD_TABLE(shc_install_exec_seq),
2034     ADD_TABLE(shc_property)
2035 };
2036 
2037 static const msi_table shc2_tables[] =
2038 {
2039     ADD_TABLE(media),
2040     ADD_TABLE(directory),
2041     ADD_TABLE(shc_file),
2042     ADD_TABLE(shc_component),
2043     ADD_TABLE(shc_feature),
2044     ADD_TABLE(shc_feature_comp),
2045     ADD_TABLE(shc_custom_action),
2046     ADD_TABLE(shc2_install_exec_seq),
2047     ADD_TABLE(shc2_property)
2048 };
2049 
2050 static const msi_table ft_tables[] =
2051 {
2052     ADD_TABLE(media),
2053     ADD_TABLE(directory),
2054     ADD_TABLE(ft_file),
2055     ADD_TABLE(ft_comp),
2056     ADD_TABLE(ft_feature),
2057     ADD_TABLE(ft_feature_comp),
2058     ADD_TABLE(ft_condition),
2059     ADD_TABLE(ft_custom_action),
2060     ADD_TABLE(ft_install_exec_seq),
2061     ADD_TABLE(property)
2062 };
2063 
2064 static const msi_table da_tables[] =
2065 {
2066     ADD_TABLE(media),
2067     ADD_TABLE(directory),
2068     ADD_TABLE(file),
2069     ADD_TABLE(component),
2070     ADD_TABLE(feature),
2071     ADD_TABLE(feature_comp),
2072     ADD_TABLE(property),
2073     ADD_TABLE(da_install_exec_seq),
2074     ADD_TABLE(da_custom_action),
2075 };
2076 
2077 static const msi_table x64_tables[] =
2078 {
2079     ADD_TABLE(media),
2080     ADD_TABLE(x64_directory),
2081     ADD_TABLE(file),
2082     ADD_TABLE(component),
2083     ADD_TABLE(feature),
2084     ADD_TABLE(feature_comp),
2085     ADD_TABLE(property),
2086     ADD_TABLE(install_exec_seq),
2087 };
2088 
2089 static const msi_table sr_tables[] =
2090 {
2091     ADD_TABLE(media),
2092     ADD_TABLE(directory),
2093     ADD_TABLE(file),
2094     ADD_TABLE(component),
2095     ADD_TABLE(feature),
2096     ADD_TABLE(feature_comp),
2097     ADD_TABLE(property),
2098     ADD_TABLE(sr_install_exec_seq),
2099     ADD_TABLE(sr_custom_action),
2100 };
2101 
2102 /* cabinet definitions */
2103 
2104 /* make the max size large so there is only one cab file */
2105 #define MEDIA_SIZE          0x7FFFFFFF
2106 #define FOLDER_THRESHOLD    900000
2107 
2108 /* the FCI callbacks */
2109 
mem_alloc(ULONG cb)2110 static void * CDECL mem_alloc(ULONG cb)
2111 {
2112     return malloc(cb);
2113 }
2114 
mem_free(void * memory)2115 static void CDECL mem_free(void *memory)
2116 {
2117     free(memory);
2118 }
2119 
get_next_cabinet(PCCAB pccab,ULONG cbPrevCab,void * pv)2120 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
2121 {
2122     sprintf(pccab->szCab, pv, pccab->iCab);
2123     return TRUE;
2124 }
2125 
progress(UINT typeStatus,ULONG cb1,ULONG cb2,void * pv)2126 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
2127 {
2128     return 0;
2129 }
2130 
file_placed(PCCAB pccab,char * pszFile,LONG cbFile,BOOL fContinuation,void * pv)2131 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
2132                              BOOL fContinuation, void *pv)
2133 {
2134     return 0;
2135 }
2136 
fci_open(char * pszFile,int oflag,int pmode,int * err,void * pv)2137 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
2138 {
2139     HANDLE handle;
2140     DWORD dwAccess = 0;
2141     DWORD dwShareMode = 0;
2142     DWORD dwCreateDisposition = OPEN_EXISTING;
2143 
2144     dwAccess = GENERIC_READ | GENERIC_WRITE;
2145     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
2146 
2147     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
2148         dwCreateDisposition = OPEN_EXISTING;
2149     else
2150         dwCreateDisposition = CREATE_NEW;
2151 
2152     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
2153                          dwCreateDisposition, 0, NULL);
2154 
2155     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
2156 
2157     return (INT_PTR)handle;
2158 }
2159 
fci_read(INT_PTR hf,void * memory,UINT cb,int * err,void * pv)2160 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2161 {
2162     HANDLE handle = (HANDLE)hf;
2163     DWORD dwRead;
2164     BOOL res;
2165 
2166     res = ReadFile(handle, memory, cb, &dwRead, NULL);
2167     ok(res, "Failed to ReadFile\n");
2168 
2169     return dwRead;
2170 }
2171 
fci_write(INT_PTR hf,void * memory,UINT cb,int * err,void * pv)2172 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2173 {
2174     HANDLE handle = (HANDLE)hf;
2175     DWORD dwWritten;
2176     BOOL res;
2177 
2178     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
2179     ok(res, "Failed to WriteFile\n");
2180 
2181     return dwWritten;
2182 }
2183 
fci_close(INT_PTR hf,int * err,void * pv)2184 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
2185 {
2186     HANDLE handle = (HANDLE)hf;
2187     ok(CloseHandle(handle), "Failed to CloseHandle\n");
2188 
2189     return 0;
2190 }
2191 
fci_seek(INT_PTR hf,LONG dist,int seektype,int * err,void * pv)2192 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
2193 {
2194     HANDLE handle = (HANDLE)hf;
2195     DWORD ret;
2196 
2197     ret = SetFilePointer(handle, dist, NULL, seektype);
2198     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
2199 
2200     return ret;
2201 }
2202 
fci_delete(char * pszFile,int * err,void * pv)2203 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
2204 {
2205     BOOL ret = DeleteFileA(pszFile);
2206     ok(ret, "Failed to DeleteFile %s\n", pszFile);
2207 
2208     return 0;
2209 }
2210 
is_process_elevated(void)2211 BOOL is_process_elevated(void)
2212 {
2213     HANDLE token;
2214     TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
2215     DWORD size;
2216     BOOL ret;
2217 
2218     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) return FALSE;
2219     ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
2220     CloseHandle(token);
2221     return (ret && type == TokenElevationTypeFull);
2222 }
2223 
check_record(MSIHANDLE rec,UINT field,LPCSTR val)2224 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
2225 {
2226     CHAR buffer[0x20];
2227     UINT r;
2228     DWORD sz;
2229 
2230     sz = sizeof buffer;
2231     r = MsiRecordGetStringA(rec, field, buffer, &sz);
2232     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
2233 }
2234 
get_temp_file(char * pszTempName,int cbTempName,void * pv)2235 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
2236 {
2237     LPSTR tempname;
2238 
2239     tempname = malloc(MAX_PATH);
2240     GetTempFileNameA(".", "xx", 0, tempname);
2241 
2242     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
2243     {
2244         lstrcpyA(pszTempName, tempname);
2245         free(tempname);
2246         return TRUE;
2247     }
2248 
2249     free(tempname);
2250     return FALSE;
2251 }
2252 
get_open_info(char * pszName,USHORT * pdate,USHORT * ptime,USHORT * pattribs,int * err,void * pv)2253 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
2254                                    USHORT *pattribs, int *err, void *pv)
2255 {
2256     BY_HANDLE_FILE_INFORMATION finfo;
2257     FILETIME filetime;
2258     HANDLE handle;
2259     DWORD attrs;
2260     BOOL res;
2261 
2262     handle = CreateFileA(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
2263                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
2264 
2265     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
2266 
2267     res = GetFileInformationByHandle(handle, &finfo);
2268     ok(res, "Expected GetFileInformationByHandle to succeed\n");
2269 
2270     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
2271     FileTimeToDosDateTime(&filetime, pdate, ptime);
2272 
2273     attrs = GetFileAttributesA(pszName);
2274     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
2275 
2276     return (INT_PTR)handle;
2277 }
2278 
add_file(HFCI hfci,const char * file,TCOMP compress)2279 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
2280 {
2281     char path[MAX_PATH];
2282     char filename[MAX_PATH];
2283 
2284     lstrcpyA(path, CURR_DIR);
2285     lstrcatA(path, "\\");
2286     lstrcatA(path, file);
2287 
2288     lstrcpyA(filename, file);
2289 
2290     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
2291                       progress, get_open_info, compress);
2292 }
2293 
set_cab_parameters(PCCAB pCabParams,const CHAR * name,DWORD max_size)2294 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
2295 {
2296     ZeroMemory(pCabParams, sizeof(CCAB));
2297 
2298     pCabParams->cb = max_size;
2299     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
2300     pCabParams->setID = 0xbeef;
2301     pCabParams->iCab = 1;
2302     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
2303     lstrcatA(pCabParams->szCabPath, "\\");
2304     lstrcpyA(pCabParams->szCab, name);
2305 }
2306 
create_cab_file(const CHAR * name,DWORD max_size,const CHAR * files)2307 void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
2308 {
2309     CCAB cabParams;
2310     LPCSTR ptr;
2311     HFCI hfci;
2312     ERF erf;
2313     BOOL res;
2314 
2315     set_cab_parameters(&cabParams, name, max_size);
2316 
2317     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2318                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2319                       get_temp_file, &cabParams, NULL);
2320 
2321     ok(hfci != NULL, "Failed to create an FCI context\n");
2322 
2323     ptr = files;
2324     while (*ptr)
2325     {
2326         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
2327         ok(res, "Failed to add file: %s\n", ptr);
2328         ptr += lstrlenA(ptr) + 1;
2329     }
2330 
2331     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2332     ok(res, "Failed to flush the cabinet\n");
2333 
2334     res = FCIDestroy(hfci);
2335     ok(res, "Failed to destroy the cabinet\n");
2336 }
2337 
get_user_dirs(void)2338 BOOL get_user_dirs(void)
2339 {
2340     HKEY hkey;
2341     DWORD type, size;
2342 
2343     if (RegOpenKeyA(HKEY_CURRENT_USER,
2344                     "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hkey))
2345         return FALSE;
2346 
2347     size = MAX_PATH;
2348     if(RegQueryValueExA(hkey, "AppData", 0, &type, (LPBYTE)APP_DATA_DIR, &size)){
2349         RegCloseKey(hkey);
2350         return FALSE;
2351     }
2352 
2353     RegCloseKey(hkey);
2354     return TRUE;
2355 }
2356 
get_system_dirs(void)2357 BOOL get_system_dirs(void)
2358 {
2359     HKEY hkey;
2360     DWORD type, size;
2361 
2362     if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion",
2363         0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hkey))
2364         return FALSE;
2365 
2366     size = MAX_PATH;
2367     if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
2368         RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size)) {
2369         RegCloseKey(hkey);
2370         return FALSE;
2371     }
2372 
2373     size = MAX_PATH;
2374     if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
2375         RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size)) {
2376         RegCloseKey(hkey);
2377         return FALSE;
2378     }
2379 
2380     size = MAX_PATH;
2381     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size)) {
2382         RegCloseKey(hkey);
2383         return FALSE;
2384     }
2385 
2386     RegCloseKey(hkey);
2387 
2388     if(!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH))
2389         return FALSE;
2390 
2391     return TRUE;
2392 }
2393 
create_file_data(LPCSTR name,LPCSTR data,DWORD size)2394 void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
2395 {
2396     HANDLE file;
2397     DWORD written;
2398 
2399     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2400     if (file == INVALID_HANDLE_VALUE)
2401         return;
2402 
2403     WriteFile(file, data, strlen(data), &written, NULL);
2404 
2405     if (size)
2406     {
2407         SetFilePointer(file, size, NULL, FILE_BEGIN);
2408         SetEndOfFile(file);
2409     }
2410 
2411     CloseHandle(file);
2412 }
2413 
create_test_files(void)2414 static void create_test_files(void)
2415 {
2416     CreateDirectoryA("msitest", NULL);
2417     create_file("msitest\\one.txt", 100);
2418     CreateDirectoryA("msitest\\first", NULL);
2419     create_file("msitest\\first\\two.txt", 100);
2420     CreateDirectoryA("msitest\\second", NULL);
2421     create_file("msitest\\second\\three.txt", 100);
2422 
2423     create_file("four.txt", 100);
2424     create_file("five.txt", 100);
2425     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
2426 
2427     create_file("msitest\\filename", 100);
2428 
2429     DeleteFileA("four.txt");
2430     DeleteFileA("five.txt");
2431 }
2432 
delete_pf(const CHAR * rel_path,BOOL is_file)2433 BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
2434 {
2435     CHAR path[MAX_PATH];
2436 
2437     lstrcpyA(path, PROG_FILES_DIR);
2438     lstrcatA(path, "\\");
2439     lstrcatA(path, rel_path);
2440 
2441     if (is_file)
2442         return DeleteFileA(path);
2443     else
2444         return RemoveDirectoryA(path);
2445 }
2446 
delete_pf_native(const CHAR * rel_path,BOOL is_file)2447 static BOOL delete_pf_native(const CHAR *rel_path, BOOL is_file)
2448 {
2449     CHAR path[MAX_PATH];
2450 
2451     lstrcpyA(path, PROG_FILES_DIR_NATIVE);
2452     lstrcatA(path, "\\");
2453     lstrcatA(path, rel_path);
2454 
2455     if (is_file)
2456         return DeleteFileA(path);
2457     else
2458         return RemoveDirectoryA(path);
2459 }
2460 
delete_cf(const CHAR * rel_path,BOOL is_file)2461 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
2462 {
2463     CHAR path[MAX_PATH];
2464 
2465     lstrcpyA(path, COMMON_FILES_DIR);
2466     lstrcatA(path, "\\");
2467     lstrcatA(path, rel_path);
2468 
2469     if (is_file)
2470         return DeleteFileA(path);
2471     else
2472         return RemoveDirectoryA(path);
2473 }
2474 
compare_pf_data(const char * filename,const char * data,DWORD size)2475 static BOOL compare_pf_data(const char *filename, const char *data, DWORD size)
2476 {
2477     DWORD read;
2478     HANDLE handle;
2479     BOOL ret = FALSE;
2480     char *buffer, path[MAX_PATH];
2481 
2482     lstrcpyA(path, PROG_FILES_DIR);
2483     lstrcatA(path, "\\");
2484     lstrcatA(path, filename);
2485 
2486     handle = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2487     if ((buffer = malloc(size)))
2488     {
2489         ReadFile(handle, buffer, size, &read, NULL);
2490         if (read == size && !memcmp(data, buffer, size)) ret = TRUE;
2491         free(buffer);
2492     }
2493     CloseHandle(handle);
2494     return ret;
2495 }
2496 
delete_test_files(void)2497 static void delete_test_files(void)
2498 {
2499     DeleteFileA("msitest.msi");
2500     DeleteFileA("msitest.cab");
2501     DeleteFileA("msitest\\second\\three.txt");
2502     DeleteFileA("msitest\\first\\two.txt");
2503     DeleteFileA("msitest\\one.txt");
2504     DeleteFileA("msitest\\filename");
2505     RemoveDirectoryA("msitest\\second");
2506     RemoveDirectoryA("msitest\\first");
2507     RemoveDirectoryA("msitest");
2508 }
2509 
delete_pf_files(void)2510 static void delete_pf_files(void)
2511 {
2512     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2513     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
2514     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2515     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
2516     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2517     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
2518     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2519     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
2520     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2521     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2522     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2523 }
2524 
write_file(const CHAR * filename,const char * data,int data_size)2525 static void write_file(const CHAR *filename, const char *data, int data_size)
2526 {
2527     DWORD size;
2528 
2529     HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
2530                             CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2531     WriteFile(hf, data, data_size, &size, NULL);
2532     CloseHandle(hf);
2533 }
2534 
write_msi_summary_info(MSIHANDLE db,INT version,INT wordcount,const char * template,const char * packagecode)2535 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount,
2536                                    const char *template, const char *packagecode)
2537 {
2538     MSIHANDLE summary;
2539     UINT r;
2540 
2541     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
2542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2543 
2544     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
2545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2546 
2547     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL, packagecode);
2548     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2549 
2550     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
2551     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2552 
2553     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
2554     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2555 
2556     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2557     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2558 
2559     /* write the summary changes back to the stream */
2560     r = MsiSummaryInfoPersist(summary);
2561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2562 
2563     MsiCloseHandle(summary);
2564 }
2565 
load_resource(const char * name)2566 static char *load_resource(const char *name)
2567 {
2568     static char path[MAX_PATH];
2569     DWORD written;
2570     HANDLE file;
2571     HRSRC res;
2572     void *ptr;
2573 
2574     GetTempFileNameA(".", name, 0, path);
2575 
2576     file = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
2577     ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %lu\n", path, GetLastError());
2578 
2579     res = FindResourceA(NULL, name, "TESTDLL");
2580     ok( res != 0, "couldn't find resource\n" );
2581     ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
2582     WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
2583     ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
2584     CloseHandle( file );
2585 
2586     return path;
2587 }
2588 
ok_callback(void * context,UINT message_type,MSIHANDLE record)2589 static INT CALLBACK ok_callback(void *context, UINT message_type, MSIHANDLE record)
2590 {
2591     if (message_type == INSTALLMESSAGE_USER)
2592     {
2593         char file[200];
2594         char msg[2000];
2595         DWORD len;
2596 
2597         len = sizeof(file);
2598         MsiRecordGetStringA(record, 2, file, &len);
2599         len = sizeof(msg);
2600         MsiRecordGetStringA(record, 5, msg, &len);
2601 
2602         todo_wine_if(MsiRecordGetInteger(record, 1))
2603         ok_(file, MsiRecordGetInteger(record, 3)) (MsiRecordGetInteger(record, 4), "%s", msg);
2604 
2605         return 1;
2606     }
2607     return 0;
2608 }
2609 
add_custom_dll(MSIHANDLE hdb)2610 static void add_custom_dll(MSIHANDLE hdb)
2611 {
2612     MSIHANDLE record;
2613     UINT res;
2614 
2615     if (!customdll)
2616         customdll = load_resource("custom.dll");
2617 
2618     MsiSetExternalUIRecord(ok_callback, INSTALLLOGMODE_USER, NULL, NULL);
2619 
2620     res = run_query(hdb, 0, "CREATE TABLE `Binary` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL PRIMARY KEY `Name`)");
2621     ok(res == ERROR_SUCCESS, "failed to create Binary table: %u\n", res);
2622 
2623     record = MsiCreateRecord(1);
2624     res = MsiRecordSetStreamA(record, 1, customdll);
2625     ok(res == ERROR_SUCCESS, "failed to add %s to stream: %u\n", customdll, res);
2626 
2627     res = run_query(hdb, record, "INSERT INTO `Binary` (`Name`, `Data`) VALUES ('custom.dll', ?)");
2628     ok(res == ERROR_SUCCESS, "failed to insert into Binary table: %u\n", res);
2629 
2630     MsiCloseHandle(record);
2631 }
2632 
create_database_wordcount(const CHAR * name,const msi_table * tables,int num_tables,INT version,INT wordcount,const char * template,const char * packagecode)2633 void create_database_wordcount(const CHAR *name, const msi_table *tables, int num_tables,
2634     INT version, INT wordcount, const char *template, const char *packagecode)
2635 {
2636     MSIHANDLE db;
2637     UINT r;
2638     WCHAR *nameW;
2639     int j, len;
2640 
2641     len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
2642     if (!(nameW = malloc( len * sizeof(WCHAR) ))) return;
2643     MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
2644 
2645     r = MsiOpenDatabaseW(nameW, MSIDBOPEN_CREATE, &db);
2646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2647 
2648     /* import the tables into the database */
2649     for (j = 0; j < num_tables; j++)
2650     {
2651         const msi_table *table = &tables[j];
2652 
2653         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
2654 
2655         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
2656         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2657 
2658         DeleteFileA(table->filename);
2659     }
2660 
2661     write_msi_summary_info(db, version, wordcount, template, packagecode);
2662     add_custom_dll(db);
2663 
2664     r = MsiDatabaseCommit(db);
2665     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2666 
2667     MsiCloseHandle(db);
2668     free( nameW );
2669 }
2670 
test_MsiInstallProduct(void)2671 static void test_MsiInstallProduct(void)
2672 {
2673     UINT r;
2674     CHAR path[MAX_PATH];
2675     LONG res;
2676     HKEY hkey;
2677     DWORD num, size, type;
2678     REGSAM access = KEY_ALL_ACCESS;
2679 
2680     if (!is_process_elevated())
2681     {
2682         skip("process is limited\n");
2683         return;
2684     }
2685 
2686     if (is_wow64)
2687         access |= KEY_WOW64_64KEY;
2688 
2689     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2690 
2691     if (0) /* crashes on Win10 1709 */
2692     {
2693         r = MsiInstallProductA(NULL, "INSTALL=ALL");
2694         ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2695 
2696         r = MsiInstallProductA(NULL, NULL);
2697         ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
2698     }
2699 
2700     /* szPackagePath is empty */
2701     r = MsiInstallProductA("", "INSTALL=ALL");
2702     ok(r == ERROR_PATH_NOT_FOUND,
2703        "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
2704 
2705     create_test_files();
2706     create_database(msifile, tables, ARRAY_SIZE(tables));
2707 
2708     /* install, don't publish */
2709     r = MsiInstallProductA(msifile, NULL);
2710     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2711     {
2712         skip("Not enough rights to perform tests\n");
2713         goto error;
2714     }
2715     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2716 
2717     delete_pf_files();
2718 
2719     res = RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", 0, access, &hkey);
2720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2721 
2722     size = MAX_PATH;
2723     type = REG_SZ;
2724     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
2725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2726     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
2727 
2728     size = MAX_PATH;
2729     type = REG_SZ;
2730     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
2731     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2732 
2733     size = sizeof(num);
2734     type = REG_DWORD;
2735     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
2736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2737     ok(num == 314, "Expected 314, got %lu\n", num);
2738 
2739     size = MAX_PATH;
2740     type = REG_SZ;
2741     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
2742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2743     ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
2744 
2745     RegDeleteKeyExA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", access, 0);
2746 
2747     /* not published, reinstall */
2748     r = MsiInstallProductA(msifile, NULL);
2749     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2750 
2751     delete_pf_files();
2752 
2753     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2754     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2755     RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest");
2756 
2757     create_database(msifile, up_tables, ARRAY_SIZE(up_tables));
2758 
2759     /* not published, RemovePreviousVersions set */
2760     r = MsiInstallProductA(msifile, NULL);
2761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2762 
2763     delete_pf_files();
2764 
2765     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2767     RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest");
2768 
2769     create_database(msifile, up2_tables, ARRAY_SIZE(up2_tables));
2770 
2771     /* not published, version number bumped */
2772     r = MsiInstallProductA(msifile, NULL);
2773     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2774 
2775     delete_pf_files();
2776 
2777     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2779     RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest");
2780 
2781     create_database(msifile, up3_tables, ARRAY_SIZE(up3_tables));
2782 
2783     /* not published, RemovePreviousVersions set and version number bumped */
2784     r = MsiInstallProductA(msifile, NULL);
2785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2786 
2787     delete_pf_files();
2788 
2789     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2790     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2791     RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest");
2792 
2793     create_database(msifile, up4_tables, ARRAY_SIZE(up4_tables));
2794 
2795     /* install, publish product */
2796     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2798 
2799     delete_pf_files();
2800 
2801     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2802     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2803 
2804     create_database(msifile, up4_tables, ARRAY_SIZE(up4_tables));
2805 
2806     /* published, reinstall */
2807     r = MsiInstallProductA(msifile, NULL);
2808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2809 
2810     delete_pf_files();
2811 
2812     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2813     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2814 
2815     create_database(msifile, up5_tables, ARRAY_SIZE(up5_tables));
2816 
2817     /* published product, RemovePreviousVersions set */
2818     r = MsiInstallProductA(msifile, NULL);
2819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2820 
2821     delete_pf_files();
2822 
2823     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2824     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2825 
2826     create_database(msifile, up6_tables, ARRAY_SIZE(up6_tables));
2827 
2828     /* published product, version number bumped */
2829     r = MsiInstallProductA(msifile, NULL);
2830     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2831 
2832     delete_pf_files();
2833 
2834     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2835     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2836 
2837     create_database(msifile, up7_tables, ARRAY_SIZE(up7_tables));
2838 
2839     /* published product, RemovePreviousVersions set and version number bumped */
2840     r = MsiInstallProductA(msifile, NULL);
2841     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2842 
2843     delete_pf_files();
2844 
2845     res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2846     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2847 
2848     r = MsiInstallProductA(msifile, "REMOVE=ALL FULL=1");
2849     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2850 
2851 error:
2852     delete_test_files();
2853     DeleteFileA(msifile);
2854 }
2855 
test_MsiSetComponentState(void)2856 static void test_MsiSetComponentState(void)
2857 {
2858     INSTALLSTATE installed, action;
2859     MSIHANDLE package;
2860     char path[MAX_PATH];
2861     UINT r;
2862 
2863     create_database(msifile, tables, ARRAY_SIZE(tables));
2864 
2865     CoInitialize(NULL);
2866 
2867     lstrcpyA(path, CURR_DIR);
2868     lstrcatA(path, "\\");
2869     lstrcatA(path, msifile);
2870 
2871     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2872 
2873     r = MsiOpenPackageA(path, &package);
2874     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2875     {
2876         skip("Not enough rights to perform tests\n");
2877         goto error;
2878     }
2879     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2880 
2881     r = MsiDoActionA(package, "CostInitialize");
2882     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2883 
2884     r = MsiDoActionA(package, "FileCost");
2885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2886 
2887     r = MsiDoActionA(package, "CostFinalize");
2888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2889 
2890     r = MsiGetComponentStateA(package, "dangler", &installed, &action);
2891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2892     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
2893     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2894 
2895     r = MsiSetComponentStateA(package, "dangler", INSTALLSTATE_SOURCE);
2896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2897 
2898     MsiCloseHandle(package);
2899 
2900 error:
2901     CoUninitialize();
2902     DeleteFileA(msifile);
2903 }
2904 
test_packagecoltypes(void)2905 static void test_packagecoltypes(void)
2906 {
2907     MSIHANDLE hdb, view, rec;
2908     char path[MAX_PATH];
2909     WCHAR pathW[MAX_PATH];
2910     LPCSTR query;
2911     UINT r, count;
2912 
2913     create_database(msifile, tables, ARRAY_SIZE(tables));
2914 
2915     CoInitialize(NULL);
2916 
2917     lstrcpyA(path, CURR_DIR);
2918     lstrcatA(path, "\\");
2919     lstrcatA(path, msifile);
2920     MultiByteToWideChar( CP_ACP, 0, path, -1, pathW, MAX_PATH );
2921 
2922     r = MsiOpenDatabaseW(pathW, MSIDBOPEN_READONLY, &hdb);
2923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2924 
2925     query = "SELECT * FROM `Media`";
2926     r = MsiDatabaseOpenViewA( hdb, query, &view );
2927     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2928 
2929     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
2930     count = MsiRecordGetFieldCount( rec );
2931     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
2932     ok(count == 6, "Expected 6, got %d\n", count);
2933     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
2934     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
2935     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
2936     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
2937     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
2938     ok(check_record(rec, 6, "Source"), "wrong column label\n");
2939     MsiCloseHandle(rec);
2940 
2941     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
2942     count = MsiRecordGetFieldCount( rec );
2943     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
2944     ok(count == 6, "Expected 6, got %d\n", count);
2945     ok(check_record(rec, 1, "i2"), "wrong column label\n");
2946     ok(check_record(rec, 2, "i4"), "wrong column label\n");
2947     ok(check_record(rec, 3, "L64"), "wrong column label\n");
2948     ok(check_record(rec, 4, "S255"), "wrong column label\n");
2949     ok(check_record(rec, 5, "S32"), "wrong column label\n");
2950     ok(check_record(rec, 6, "S72"), "wrong column label\n");
2951 
2952     MsiCloseHandle(rec);
2953     MsiCloseHandle(view);
2954     MsiCloseHandle(hdb);
2955     CoUninitialize();
2956 
2957     DeleteFileA(msifile);
2958 }
2959 
create_cc_test_files(void)2960 static void create_cc_test_files(void)
2961 {
2962     CCAB cabParams;
2963     HFCI hfci;
2964     ERF erf;
2965     static CHAR cab_context[] = "test%d.cab";
2966     BOOL res;
2967 
2968     create_file("maximus", 500);
2969     create_file("augustus", 50000);
2970     create_file("tiberius", 500);
2971     create_file("caesar", 500);
2972 
2973     set_cab_parameters(&cabParams, "test1.cab", 40000);
2974 
2975     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2976                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2977                       get_temp_file, &cabParams, cab_context);
2978     ok(hfci != NULL, "Failed to create an FCI context\n");
2979 
2980     res = add_file(hfci, "maximus", tcompTYPE_NONE);
2981     ok(res, "Failed to add file maximus\n");
2982 
2983     res = add_file(hfci, "augustus", tcompTYPE_NONE);
2984     ok(res, "Failed to add file augustus\n");
2985 
2986     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
2987     ok(res, "Failed to add file tiberius\n");
2988 
2989     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2990     ok(res, "Failed to flush the cabinet\n");
2991 
2992     res = FCIDestroy(hfci);
2993     ok(res, "Failed to destroy the cabinet\n");
2994 
2995     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
2996 
2997     DeleteFileA("maximus");
2998     DeleteFileA("augustus");
2999     DeleteFileA("tiberius");
3000     DeleteFileA("caesar");
3001 }
3002 
delete_cab_files(void)3003 void delete_cab_files(void)
3004 {
3005     SHFILEOPSTRUCTA shfl;
3006     CHAR path[MAX_PATH+10];
3007 
3008     lstrcpyA(path, CURR_DIR);
3009     lstrcatA(path, "\\*.cab");
3010     path[strlen(path) + 1] = '\0';
3011 
3012     shfl.hwnd = NULL;
3013     shfl.wFunc = FO_DELETE;
3014     shfl.pFrom = path;
3015     shfl.pTo = NULL;
3016     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
3017 
3018     SHFileOperationA(&shfl);
3019 }
3020 
test_continuouscabs(void)3021 static void test_continuouscabs(void)
3022 {
3023     UINT r;
3024 
3025     if (!is_process_elevated())
3026     {
3027         skip("process is limited\n");
3028         return;
3029     }
3030 
3031     create_cc_test_files();
3032     create_database(msifile, cc_tables, ARRAY_SIZE(cc_tables));
3033 
3034     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3035 
3036     r = MsiInstallProductA(msifile, NULL);
3037     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3038     {
3039         skip("Not enough rights to perform tests\n");
3040         goto error;
3041     }
3042     else
3043     {
3044         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3045         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3046         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3047         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3048         ok(delete_pf("msitest", FALSE), "Directory not created\n");
3049     }
3050 
3051     delete_cab_files();
3052     DeleteFileA(msifile);
3053 
3054     create_cc_test_files();
3055     create_database(msifile, cc2_tables, ARRAY_SIZE(cc2_tables));
3056 
3057     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3058 
3059     r = MsiInstallProductA(msifile, NULL);
3060     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3061     {
3062         skip("Not enough rights to perform tests\n");
3063     }
3064     else
3065     {
3066         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3067         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3068         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3069         ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
3070         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3071         ok(delete_pf("msitest", FALSE), "Directory not created\n");
3072     }
3073 
3074     delete_cab_files();
3075     DeleteFileA(msifile);
3076 
3077     /* Tests to show that only msi cab filename is taken in case of mismatch with the one given by previous cab */
3078 
3079     /* Filename from cab is right and the one from msi is wrong */
3080     create_cc_test_files();
3081     create_database(msifile, cc3_tables, ARRAY_SIZE(cc3_tables));
3082 
3083     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3084 
3085     r = MsiInstallProductA(msifile, NULL);
3086     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3087     {
3088         skip("Not enough rights to perform tests\n");
3089     }
3090     else
3091     {
3092         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3093         todo_wine ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3094         ok(!delete_pf("msitest\\caesar", TRUE), "File installed\n");
3095         todo_wine ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
3096         todo_wine ok(!delete_pf("msitest", FALSE), "Directory created\n");
3097     }
3098 
3099     delete_cab_files();
3100     DeleteFileA(msifile);
3101 
3102     /* Filename from msi is right and the one from cab is wrong */
3103     create_cc_test_files();
3104     ok(MoveFileA("test2.cab", "test2_.cab"), "Cannot rename test2.cab to test2_.cab\n");
3105     create_database(msifile, cc3_tables, ARRAY_SIZE(cc3_tables));
3106 
3107     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3108 
3109     r = MsiInstallProductA(msifile, NULL);
3110     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3111     {
3112         skip("Not enough rights to perform tests\n");
3113     }
3114     else
3115     {
3116         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3117         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3118         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3119         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3120         ok(delete_pf("msitest", FALSE), "Directory not created\n");
3121     }
3122 
3123 error:
3124     delete_cab_files();
3125     DeleteFileA(msifile);
3126 }
3127 
test_caborder(void)3128 static void test_caborder(void)
3129 {
3130     UINT r;
3131 
3132     create_file("imperator", 100);
3133     create_file("maximus", 500);
3134     create_file("augustus", 50000);
3135     create_file("caesar", 500);
3136 
3137     create_database(msifile, cc_tables, ARRAY_SIZE(cc_tables));
3138 
3139     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3140 
3141     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3142     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3143     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3144 
3145     r = MsiInstallProductA(msifile, NULL);
3146     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3147     {
3148         skip("Not enough rights to perform tests\n");
3149         goto error;
3150     }
3151     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3152     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3153     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3154     todo_wine
3155     {
3156         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3157         ok(!delete_pf("msitest", FALSE), "Directory is created\n");
3158     }
3159 
3160     delete_cab_files();
3161 
3162     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
3163     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
3164     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3165 
3166     r = MsiInstallProductA(msifile, NULL);
3167     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3168     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3169     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3170     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3171     ok(!delete_pf("msitest", FALSE), "Directory is created\n");
3172 
3173     delete_cab_files();
3174     DeleteFileA(msifile);
3175 
3176     create_cc_test_files();
3177     create_database(msifile, co_tables, ARRAY_SIZE(co_tables));
3178 
3179     r = MsiInstallProductA(msifile, NULL);
3180     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3181     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3182     ok(!delete_pf("msitest", FALSE), "Directory is created\n");
3183     todo_wine
3184     {
3185         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3186         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3187     }
3188 
3189     delete_cab_files();
3190     DeleteFileA(msifile);
3191 
3192     create_cc_test_files();
3193     create_database(msifile, co2_tables, ARRAY_SIZE(co2_tables));
3194 
3195     r = MsiInstallProductA(msifile, NULL);
3196     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3197     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3198     todo_wine
3199     {
3200         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3201         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3202         ok(!delete_pf("msitest", FALSE), "Directory is created\n");
3203     }
3204 
3205 error:
3206     delete_cab_files();
3207     DeleteFileA("imperator");
3208     DeleteFileA("maximus");
3209     DeleteFileA("augustus");
3210     DeleteFileA("caesar");
3211     DeleteFileA(msifile);
3212 }
3213 
test_mixedmedia(void)3214 static void test_mixedmedia(void)
3215 {
3216     UINT r;
3217 
3218     if (!is_process_elevated())
3219     {
3220         skip("process is limited\n");
3221         return;
3222     }
3223 
3224     CreateDirectoryA("msitest", NULL);
3225     create_file("msitest\\maximus", 500);
3226     create_file("msitest\\augustus", 500);
3227     create_file("caesar", 500);
3228 
3229     create_database(msifile, mm_tables, ARRAY_SIZE(mm_tables));
3230 
3231     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3232 
3233     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
3234 
3235     r = MsiInstallProductA(msifile, NULL);
3236     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3237     {
3238         skip("Not enough rights to perform tests\n");
3239         goto error;
3240     }
3241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3242     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3243     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3244     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3245     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3246 
3247 error:
3248     /* Delete the files in the temp (current) folder */
3249     DeleteFileA("msitest\\maximus");
3250     DeleteFileA("msitest\\augustus");
3251     RemoveDirectoryA("msitest");
3252     DeleteFileA("caesar");
3253     DeleteFileA("test1.cab");
3254     DeleteFileA(msifile);
3255 }
3256 
test_samesequence(void)3257 static void test_samesequence(void)
3258 {
3259     UINT r;
3260 
3261     create_cc_test_files();
3262     create_database(msifile, ss_tables, ARRAY_SIZE(ss_tables));
3263 
3264     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3265 
3266     r = MsiInstallProductA(msifile, NULL);
3267     if (r == ERROR_INSTALL_FAILURE)
3268     {
3269         win_skip("unprivileged user?\n");
3270         goto error;
3271     }
3272     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3273     if (r == ERROR_SUCCESS)
3274     {
3275         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3276         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3277         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3278         ok(delete_pf("msitest", FALSE), "Directory not created\n");
3279     }
3280 
3281 error:
3282     delete_cab_files();
3283     DeleteFileA(msifile);
3284 }
3285 
test_uiLevelFlags(void)3286 static void test_uiLevelFlags(void)
3287 {
3288     UINT r;
3289 
3290     create_cc_test_files();
3291     create_database(msifile, ui_tables, ARRAY_SIZE(ui_tables));
3292 
3293     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
3294 
3295     r = MsiInstallProductA(msifile, NULL);
3296     if (r == ERROR_INSTALL_FAILURE)
3297     {
3298         win_skip("unprivileged user?\n");
3299         goto error;
3300     }
3301 
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3303     if (r == ERROR_SUCCESS)
3304     {
3305         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
3306         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3307         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3308         ok(delete_pf("msitest", FALSE), "Directory not created\n");
3309     }
3310 
3311 error:
3312     delete_cab_files();
3313     DeleteFileA(msifile);
3314 }
3315 
file_matches(LPSTR path)3316 static BOOL file_matches(LPSTR path)
3317 {
3318     CHAR buf[MAX_PATH];
3319     HANDLE file;
3320     DWORD size;
3321 
3322     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3323                        NULL, OPEN_EXISTING, 0, NULL);
3324     ZeroMemory(buf, MAX_PATH);
3325     ReadFile(file, buf, 15, &size, NULL);
3326     CloseHandle(file);
3327 
3328     return !lstrcmpA(buf, "msitest\\maximus");
3329 }
3330 
test_readonlyfile(void)3331 static void test_readonlyfile(void)
3332 {
3333     UINT r;
3334     DWORD size;
3335     HANDLE file;
3336     CHAR path[MAX_PATH];
3337 
3338     if (!is_process_elevated())
3339     {
3340         skip("process is limited\n");
3341         return;
3342     }
3343 
3344     CreateDirectoryA("msitest", NULL);
3345     create_file("msitest\\maximus", 500);
3346     create_database(msifile, rof_tables, ARRAY_SIZE(rof_tables));
3347 
3348     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3349 
3350     lstrcpyA(path, PROG_FILES_DIR);
3351     lstrcatA(path, "\\msitest");
3352     CreateDirectoryA(path, NULL);
3353 
3354     lstrcatA(path, "\\maximus");
3355     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3356                        NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3357 
3358     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3359     CloseHandle(file);
3360 
3361     r = MsiInstallProductA(msifile, NULL);
3362     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3363     {
3364         skip("Not enough rights to perform tests\n");
3365         goto error;
3366     }
3367     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3368     ok(file_matches(path), "Expected file to be overwritten\n");
3369     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3370     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3371 
3372 error:
3373     /* Delete the files in the temp (current) folder */
3374     DeleteFileA("msitest\\maximus");
3375     RemoveDirectoryA("msitest");
3376     DeleteFileA(msifile);
3377 }
3378 
test_readonlyfile_cab(void)3379 static void test_readonlyfile_cab(void)
3380 {
3381     UINT r;
3382     DWORD size;
3383     HANDLE file;
3384     CHAR path[MAX_PATH];
3385     CHAR buf[16];
3386 
3387     if (!is_process_elevated())
3388     {
3389         skip("process is limited\n");
3390         return;
3391     }
3392 
3393     CreateDirectoryA("msitest", NULL);
3394     create_file("maximus", 500);
3395     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3396     DeleteFileA("maximus");
3397 
3398     create_database(msifile, rofc_tables, ARRAY_SIZE(rofc_tables));
3399 
3400     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3401 
3402     lstrcpyA(path, PROG_FILES_DIR);
3403     lstrcatA(path, "\\msitest");
3404     CreateDirectoryA(path, NULL);
3405 
3406     lstrcatA(path, "\\maximus");
3407     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3408                        NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3409 
3410     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3411     CloseHandle(file);
3412 
3413     r = MsiInstallProductA(msifile, NULL);
3414     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3415     {
3416         skip("Not enough rights to perform tests\n");
3417         goto error;
3418     }
3419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3420 
3421     memset( buf, 0, sizeof(buf) );
3422     if ((file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3423                             NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
3424     {
3425         ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
3426         CloseHandle(file);
3427     }
3428     ok(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "Expected file to be overwritten, got '%s'\n", buf);
3429     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3430     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3431 
3432 error:
3433     /* Delete the files in the temp (current) folder */
3434     delete_cab_files();
3435     DeleteFileA("msitest\\maximus");
3436     RemoveDirectoryA("msitest");
3437     DeleteFileA(msifile);
3438 }
3439 
test_setdirproperty(void)3440 static void test_setdirproperty(void)
3441 {
3442     UINT r;
3443 
3444     if (!is_process_elevated())
3445     {
3446         skip("process is limited\n");
3447         return;
3448     }
3449 
3450     CreateDirectoryA("msitest", NULL);
3451     create_file("msitest\\maximus", 500);
3452     create_database(msifile, sdp_tables, ARRAY_SIZE(sdp_tables));
3453 
3454     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3455 
3456     r = MsiInstallProductA(msifile, NULL);
3457     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3458     {
3459         skip("Not enough rights to perform tests\n");
3460         goto error;
3461     }
3462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3463     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
3464     ok(delete_cf("msitest", FALSE), "Directory not created\n");
3465 
3466 error:
3467     /* Delete the files in the temp (current) folder */
3468     DeleteFileA(msifile);
3469     DeleteFileA("msitest\\maximus");
3470     RemoveDirectoryA("msitest");
3471 }
3472 
test_cabisextracted(void)3473 static void test_cabisextracted(void)
3474 {
3475     UINT r;
3476 
3477     if (!is_process_elevated())
3478     {
3479         skip("process is limited\n");
3480         return;
3481     }
3482 
3483     CreateDirectoryA("msitest", NULL);
3484     create_file("msitest\\gaius", 500);
3485     create_file("maximus", 500);
3486     create_file("augustus", 500);
3487     create_file("caesar", 500);
3488 
3489     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3490     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3491     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3492 
3493     create_database(msifile, cie_tables, ARRAY_SIZE(cie_tables));
3494 
3495     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3496 
3497     r = MsiInstallProductA(msifile, NULL);
3498     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3499     {
3500         skip("Not enough rights to perform tests\n");
3501         goto error;
3502     }
3503     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3504     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3505     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3506     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3507     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
3508     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3509 
3510 error:
3511     /* Delete the files in the temp (current) folder */
3512     delete_cab_files();
3513     DeleteFileA(msifile);
3514     DeleteFileA("maximus");
3515     DeleteFileA("augustus");
3516     DeleteFileA("caesar");
3517     DeleteFileA("msitest\\gaius");
3518     RemoveDirectoryA("msitest");
3519 }
3520 
file_exists(const char * file)3521 BOOL file_exists(const char *file)
3522 {
3523     return GetFileAttributesA(file) != INVALID_FILE_ATTRIBUTES;
3524 }
3525 
pf_exists(const char * file)3526 BOOL pf_exists(const char *file)
3527 {
3528     CHAR path[MAX_PATH];
3529 
3530     lstrcpyA(path, PROG_FILES_DIR);
3531     lstrcatA(path, "\\");
3532     lstrcatA(path, file);
3533 
3534     return file_exists(path);
3535 }
3536 
delete_pfmsitest_files(void)3537 static void delete_pfmsitest_files(void)
3538 {
3539     SHFILEOPSTRUCTA shfl;
3540     CHAR path[MAX_PATH+11];
3541 
3542     lstrcpyA(path, PROG_FILES_DIR);
3543     lstrcatA(path, "\\msitest\\*");
3544     path[strlen(path) + 1] = '\0';
3545 
3546     shfl.hwnd = NULL;
3547     shfl.wFunc = FO_DELETE;
3548     shfl.pFrom = path;
3549     shfl.pTo = NULL;
3550     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT | FOF_NOERRORUI;
3551 
3552     SHFileOperationA(&shfl);
3553 
3554     lstrcpyA(path, PROG_FILES_DIR);
3555     lstrcatA(path, "\\msitest");
3556     RemoveDirectoryA(path);
3557 }
3558 
run_query(MSIHANDLE hdb,MSIHANDLE hrec,const char * query)3559 UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
3560 {
3561     MSIHANDLE hview = 0;
3562     UINT r;
3563 
3564     r = MsiDatabaseOpenViewA(hdb, query, &hview);
3565     if(r != ERROR_SUCCESS)
3566         return r;
3567 
3568     r = MsiViewExecute(hview, hrec);
3569     if(r == ERROR_SUCCESS)
3570         r = MsiViewClose(hview);
3571     MsiCloseHandle(hview);
3572     return r;
3573 }
3574 
set_transform_summary_info(void)3575 static void set_transform_summary_info(void)
3576 {
3577     UINT r;
3578     MSIHANDLE suminfo = 0;
3579 
3580     /* build summary info */
3581     r = MsiGetSummaryInformationA(0, mstfile, 3, &suminfo);
3582     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
3583 
3584     r = MsiSummaryInfoSetPropertyA(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3585     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3586 
3587     r = MsiSummaryInfoSetPropertyA(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3588                                    "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3589                                    "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3590                                    "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
3591     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
3592 
3593     r = MsiSummaryInfoSetPropertyA(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3594     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3595 
3596     r = MsiSummaryInfoPersist(suminfo);
3597     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
3598 
3599     r = MsiCloseHandle(suminfo);
3600     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
3601 }
3602 
generate_transform(void)3603 static void generate_transform(void)
3604 {
3605     MSIHANDLE hdb1, hdb2;
3606     LPCSTR query;
3607     UINT r;
3608 
3609     /* start with two identical databases */
3610     CopyFileA(msifile, msifile2, FALSE);
3611 
3612     r = MsiOpenDatabaseW(msifile2W, MSIDBOPEN_TRANSACT, &hdb1);
3613     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3614 
3615     r = MsiDatabaseCommit(hdb1);
3616     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
3617 
3618     r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_READONLY, &hdb2);
3619     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3620 
3621     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
3622     r = run_query(hdb1, 0, query);
3623     ok(r == ERROR_SUCCESS, "failed to add property\n");
3624 
3625     /* database needs to be committed */
3626     MsiDatabaseCommit(hdb1);
3627 
3628     r = MsiDatabaseGenerateTransformA(hdb1, hdb2, mstfile, 0, 0);
3629     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
3630 
3631     r = MsiCreateTransformSummaryInfoA(hdb2, hdb2, mstfile, 0, 0);
3632     todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3633 
3634     MsiCloseHandle(hdb1);
3635     MsiCloseHandle(hdb2);
3636 }
3637 
3638 /* data for generating a transform */
3639 
3640 /* tables transform names - encoded as they would be in an msi database file */
3641 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3642 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3643 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3644 
3645 /* data in each table */
3646 static const char data1[] = /* _StringData */
3647     "propval";  /* all the strings squashed together */
3648 
3649 static const WCHAR data2[] = { /* _StringPool */
3650 /*  len, refs */
3651     0,   0,    /* string 0 ''     */
3652     4,   1,    /* string 1 'prop' */
3653     3,   1,    /* string 2 'val'  */
3654 };
3655 
3656 static const WCHAR data3[] = { /* Property */
3657     0x0201, 0x0001, 0x0002,
3658 };
3659 
3660 static const struct {
3661     LPCWSTR name;
3662     const void *data;
3663     DWORD size;
3664 } table_transform_data[] =
3665 {
3666     { name1, data1, sizeof data1 - 1 },
3667     { name2, data2, sizeof data2 },
3668     { name3, data3, sizeof data3 },
3669 };
3670 
generate_transform_manual(void)3671 static void generate_transform_manual(void)
3672 {
3673     IStorage *stg = NULL;
3674     IStream *stm;
3675     WCHAR name[0x20];
3676     HRESULT r;
3677     DWORD i, count;
3678     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
3679 
3680     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
3681 
3682     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
3683 
3684     r = StgCreateDocfile(name, mode, 0, &stg);
3685     ok(r == S_OK, "failed to create storage\n");
3686     if (!stg)
3687         return;
3688 
3689     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
3690     ok(r == S_OK, "failed to set storage type\n");
3691 
3692     for (i=0; i<ARRAY_SIZE(table_transform_data); i++)
3693     {
3694         r = IStorage_CreateStream(stg, table_transform_data[i].name,
3695                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3696         if (FAILED(r))
3697         {
3698             ok(0, "failed to create stream %#lx\n", r);
3699             continue;
3700         }
3701 
3702         r = IStream_Write(stm, table_transform_data[i].data,
3703                           table_transform_data[i].size, &count);
3704         if (FAILED(r) || count != table_transform_data[i].size)
3705             ok(0, "failed to write stream\n");
3706         IStream_Release(stm);
3707     }
3708 
3709     IStorage_Release(stg);
3710 
3711     set_transform_summary_info();
3712 }
3713 
test_transformprop(void)3714 static void test_transformprop(void)
3715 {
3716     UINT r;
3717 
3718     if (!is_process_elevated())
3719     {
3720         skip("process is limited\n");
3721         return;
3722     }
3723 
3724     CreateDirectoryA("msitest", NULL);
3725     create_file("msitest\\augustus", 500);
3726 
3727     create_database(msifile, tp_tables, ARRAY_SIZE(tp_tables));
3728 
3729     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3730 
3731     r = MsiInstallProductA(msifile, NULL);
3732     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3733     {
3734         skip("Not enough rights to perform tests\n");
3735         goto error;
3736     }
3737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3738     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3739     ok(!delete_pf("msitest", FALSE), "Directory created\n");
3740 
3741     if (0)
3742         generate_transform();
3743     else
3744         generate_transform_manual();
3745 
3746     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
3747     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3748     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3749     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3750 
3751 error:
3752     /* Delete the files in the temp (current) folder */
3753     DeleteFileA(msifile);
3754     DeleteFileA(msifile2);
3755     DeleteFileA(mstfile);
3756     DeleteFileA("msitest\\augustus");
3757     RemoveDirectoryA("msitest");
3758 }
3759 
test_currentworkingdir(void)3760 static void test_currentworkingdir(void)
3761 {
3762     UINT r;
3763     CHAR drive[MAX_PATH], path[MAX_PATH + 12];
3764     LPSTR ptr;
3765 
3766     if (!is_process_elevated())
3767     {
3768         skip("process is limited\n");
3769         return;
3770     }
3771 
3772     CreateDirectoryA("msitest", NULL);
3773     create_file("msitest\\augustus", 500);
3774 
3775     create_database(msifile, cwd_tables, ARRAY_SIZE(cwd_tables));
3776 
3777     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3778 
3779     CreateDirectoryA("diffdir", NULL);
3780     SetCurrentDirectoryA("diffdir");
3781 
3782     sprintf(path, "..\\%s", msifile);
3783     r = MsiInstallProductA(path, NULL);
3784     todo_wine
3785     {
3786         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
3787         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3788         ok(!delete_pf("msitest", FALSE), "Directory created\n");
3789     }
3790 
3791     sprintf(path, "%s\\%s", CURR_DIR, msifile);
3792     r = MsiInstallProductA(path, NULL);
3793     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3794     {
3795         skip("Not enough rights to perform tests\n");
3796         goto error;
3797     }
3798     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3799     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3800     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3801 
3802     lstrcpyA(drive, CURR_DIR);
3803     drive[2] = '\\';
3804     drive[3] = '\0';
3805     SetCurrentDirectoryA(drive);
3806 
3807     lstrcpyA(path, CURR_DIR);
3808     if (path[lstrlenA(path) - 1] != '\\') lstrcatA(path, "\\");
3809     lstrcatA(path, msifile);
3810     ptr = strchr(path, ':');
3811     ptr +=2;
3812 
3813     r = MsiInstallProductA(ptr, NULL);
3814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3815     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3816     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3817 
3818 error:
3819     SetCurrentDirectoryA(CURR_DIR);
3820     DeleteFileA(msifile);
3821     DeleteFileA("msitest\\augustus");
3822     RemoveDirectoryA("msitest");
3823     RemoveDirectoryA("diffdir");
3824 }
3825 
set_admin_summary_info(const WCHAR * name)3826 static void set_admin_summary_info(const WCHAR *name)
3827 {
3828     MSIHANDLE db, summary;
3829     UINT r;
3830 
3831     r = MsiOpenDatabaseW(name, MSIDBOPEN_DIRECT, &db);
3832     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3833 
3834     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
3835     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3836 
3837     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
3838     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3839 
3840     /* write the summary changes back to the stream */
3841     r = MsiSummaryInfoPersist(summary);
3842     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3843 
3844     MsiCloseHandle(summary);
3845 
3846     r = MsiDatabaseCommit(db);
3847     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3848 
3849     MsiCloseHandle(db);
3850 }
3851 
test_admin(void)3852 static void test_admin(void)
3853 {
3854     UINT r;
3855 
3856     CreateDirectoryA("msitest", NULL);
3857     create_file("msitest\\augustus", 500);
3858 
3859     create_database(msifile, adm_tables, ARRAY_SIZE(adm_tables));
3860     set_admin_summary_info(msifileW);
3861 
3862     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3863 
3864     r = MsiInstallProductA(msifile, NULL);
3865     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3866     {
3867         skip("Not enough rights to perform tests\n");
3868         goto error;
3869     }
3870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3871     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3872     ok(!delete_pf("msitest", FALSE), "Directory created\n");
3873     ok(!DeleteFileA("c:\\msitest\\augustus"), "File installed\n");
3874     ok(!RemoveDirectoryA("c:\\msitest"), "File installed\n");
3875 
3876     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
3877     todo_wine
3878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3879     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3880     ok(!delete_pf("msitest", FALSE), "Directory created\n");
3881     todo_wine
3882     {
3883         ok(DeleteFileA("c:\\msitest\\augustus"), "File not installed\n");
3884         ok(RemoveDirectoryA("c:\\msitest"), "File not installed\n");
3885     }
3886 
3887 error:
3888     DeleteFileA(msifile);
3889     DeleteFileA("msitest\\augustus");
3890     RemoveDirectoryA("msitest");
3891 }
3892 
set_admin_property_stream(LPCSTR file)3893 static void set_admin_property_stream(LPCSTR file)
3894 {
3895     IStorage *stg;
3896     IStream *stm;
3897     WCHAR fileW[MAX_PATH];
3898     HRESULT hr;
3899     DWORD count;
3900     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
3901 
3902     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
3903 
3904     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
3905     ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
3906     if (!stg)
3907         return;
3908 
3909     hr = IStorage_CreateStream(stg, L"\x41ca\x4330\x3e71\x44b5\x4233\x45f5\x422c\x4836",
3910                                STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3911     ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
3912 
3913     hr = IStream_Write(stm, L"MYPROP=2718 MyProp=42", sizeof(L"MYPROP=2718 MyProp=42"), &count);
3914     ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
3915 
3916     IStream_Release(stm);
3917     IStorage_Release(stg);
3918 }
3919 
test_adminprops(void)3920 static void test_adminprops(void)
3921 {
3922     UINT r;
3923 
3924     if (!is_process_elevated())
3925     {
3926         skip("process is limited\n");
3927         return;
3928     }
3929 
3930     CreateDirectoryA("msitest", NULL);
3931     create_file("msitest\\augustus", 500);
3932 
3933     create_database(msifile, amp_tables, ARRAY_SIZE(amp_tables));
3934     set_admin_summary_info(msifileW);
3935     set_admin_property_stream(msifile);
3936 
3937     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3938 
3939     r = MsiInstallProductA(msifile, NULL);
3940     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3941     {
3942         skip("Not enough rights to perform tests\n");
3943         goto error;
3944     }
3945     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3946     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
3947     ok(delete_pf("msitest", FALSE), "Directory created\n");
3948 
3949 error:
3950     DeleteFileA(msifile);
3951     DeleteFileA("msitest\\augustus");
3952     RemoveDirectoryA("msitest");
3953 }
3954 
create_pf_data(LPCSTR file,LPCSTR data,BOOL is_file)3955 void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
3956 {
3957     CHAR path[MAX_PATH];
3958 
3959     lstrcpyA(path, PROG_FILES_DIR);
3960     lstrcatA(path, "\\");
3961     lstrcatA(path, file);
3962 
3963     if (is_file)
3964         create_file_data(path, data, 500);
3965     else
3966         CreateDirectoryA(path, NULL);
3967 }
3968 
3969 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
3970 
test_missingcab(void)3971 static void test_missingcab(void)
3972 {
3973     UINT r;
3974 
3975     if (!is_process_elevated())
3976     {
3977         skip("process is limited\n");
3978         return;
3979     }
3980 
3981     CreateDirectoryA("msitest", NULL);
3982     create_file("msitest\\augustus", 500);
3983     create_file("maximus", 500);
3984     create_file("tiberius", 500);
3985 
3986     create_database(msifile, mc_tables, ARRAY_SIZE(mc_tables));
3987 
3988     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3989 
3990     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3991     create_cab_file("test4.cab", MEDIA_SIZE, "tiberius\0");
3992 
3993     create_pf("msitest", FALSE);
3994     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
3995     create_pf_data("msitest\\tiberius", "abcdefgh", TRUE);
3996 
3997     r = MsiInstallProductA(msifile, NULL);
3998     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3999     {
4000         skip("Not enough rights to perform tests\n");
4001         goto error;
4002     }
4003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4004     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4005     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4006     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4007     ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n");
4008     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
4009     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
4010     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4011 
4012     create_pf("msitest", FALSE);
4013     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4014     create_pf_data("msitest\\tiberius", "abcdefgh", TRUE);
4015     create_pf("msitest\\gaius", TRUE);
4016 
4017     r = MsiInstallProductA(msifile, "GAIUS=1");
4018     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4019     todo_wine
4020     {
4021         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
4022         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4023     }
4024     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
4025     ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n");
4026     ok(delete_pf("msitest\\tiberius", TRUE), "File removed\n");
4027     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
4028     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4029 
4030 error:
4031     delete_pf("msitest", FALSE);
4032     DeleteFileA("msitest\\augustus");
4033     RemoveDirectoryA("msitest");
4034     DeleteFileA("maximus");
4035     DeleteFileA("tiberius");
4036     DeleteFileA("test1.cab");
4037     DeleteFileA("test4.cab");
4038     DeleteFileA(msifile);
4039 }
4040 
test_sourcefolder(void)4041 static void test_sourcefolder(void)
4042 {
4043     UINT r;
4044 
4045     if (!is_process_elevated())
4046     {
4047         skip("process is limited\n");
4048         return;
4049     }
4050 
4051     CreateDirectoryA("msitest", NULL);
4052     create_file("augustus", 500);
4053 
4054     create_database(msifile, sf_tables, ARRAY_SIZE(sf_tables));
4055 
4056     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4057 
4058     r = MsiInstallProductA(msifile, NULL);
4059     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4060     {
4061         skip("Not enough rights to perform tests\n");
4062         goto error;
4063     }
4064     ok(r == ERROR_INSTALL_FAILURE,
4065        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4066     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4067     todo_wine
4068     {
4069         ok(!delete_pf("msitest", FALSE), "Directory created\n");
4070     }
4071     RemoveDirectoryA("msitest");
4072 
4073     r = MsiInstallProductA(msifile, NULL);
4074     ok(r == ERROR_INSTALL_FAILURE,
4075        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4076     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4077     todo_wine
4078     {
4079         ok(!delete_pf("msitest", FALSE), "Directory created\n");
4080     }
4081 
4082 error:
4083     DeleteFileA(msifile);
4084     DeleteFileA("augustus");
4085 }
4086 
test_customaction1(void)4087 static void test_customaction1(void)
4088 {
4089     MSIHANDLE hdb, record;
4090     UINT r;
4091 
4092     create_test_files();
4093     create_database(msifile, ca1_tables, ARRAY_SIZE(ca1_tables));
4094 
4095     /* create a test table */
4096     MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb);
4097     run_query(hdb, 0, "CREATE TABLE `Test` (`Name` CHAR(10), `Number` INTEGER, `Data` OBJECT PRIMARY KEY `Name`)");
4098     create_file("unus", 10);
4099     create_file("duo", 10);
4100     record = MsiCreateRecord(1);
4101     MsiRecordSetStreamA(record, 1, "unus");
4102     run_query(hdb, record, "INSERT INTO `Test` (`Name`, `Number`, `Data`) VALUES ('one', 1, ?)");
4103     MsiRecordSetStreamA(record, 1, "duo");
4104     run_query(hdb, record, "INSERT INTO `Test` (`Name`, `Number`, `Data`) VALUES ('two', 2, ?)");
4105     MsiDatabaseCommit(hdb);
4106     MsiCloseHandle(hdb);
4107 
4108     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4109 
4110     r = MsiInstallProductA(msifile, "MAIN_TEST=1");
4111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4112 
4113     /* Test return values */
4114     r = MsiInstallProductA(msifile, "TEST_RETVAL=0");
4115     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4116 
4117     r = MsiInstallProductA(msifile, "TEST_RETVAL=1626"); /* ERROR_FUNCTION_NOT_CALLED */
4118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4119 
4120     r = MsiInstallProductA(msifile, "TEST_RETVAL=1602");
4121     ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %u\n", r);
4122 
4123     r = MsiInstallProductA(msifile, "TEST_RETVAL=259"); /* ERROR_NO_MORE_ITEMS */
4124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4125 
4126     /* any other error maps to ERROR_INSTALL_FAILURE */
4127     r = MsiInstallProductA(msifile, "TEST_RETVAL=1");
4128     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4129 
4130     /* Custom actions execute in the same process, but they don't retain state */
4131     r = MsiInstallProductA(msifile, "TEST_PROCESS=1");
4132     ok(!r, "got %u\n", r);
4133 
4134     /* test asynchronous actions (msidbCustomActionTypeAsync) */
4135     r = MsiInstallProductA(msifile, "TEST_ASYNC=1");
4136     ok(!r, "got %u\n", r);
4137 
4138     delete_test_files();
4139     DeleteFileA(msifile);
4140     DeleteFileA("unus");
4141     DeleteFileA("duo");
4142 }
4143 
test_customaction51(void)4144 static void test_customaction51(void)
4145 {
4146     UINT r;
4147 
4148     if (!is_process_elevated())
4149     {
4150         skip("process is limited\n");
4151         return;
4152     }
4153 
4154     CreateDirectoryA("msitest", NULL);
4155     create_file("msitest\\augustus", 500);
4156 
4157     create_database(msifile, ca51_tables, ARRAY_SIZE(ca51_tables));
4158 
4159     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4160 
4161     r = MsiInstallProductA(msifile, NULL);
4162     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4163     {
4164         skip("Not enough rights to perform tests\n");
4165         goto error;
4166     }
4167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4168     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4169     ok(delete_pf("msitest", FALSE), "Directory created\n");
4170 
4171 error:
4172     DeleteFileA(msifile);
4173     DeleteFileA("msitest\\augustus");
4174     RemoveDirectoryA("msitest");
4175 }
4176 
test_installstate(void)4177 static void test_installstate(void)
4178 {
4179     UINT r;
4180 
4181     if (!is_process_elevated())
4182     {
4183         skip("process is limited\n");
4184         return;
4185     }
4186 
4187     CreateDirectoryA("msitest", NULL);
4188     create_file("msitest\\alpha", 500);
4189     create_file("msitest\\beta", 500);
4190     create_file("msitest\\gamma", 500);
4191     create_file("msitest\\theta", 500);
4192     create_file("msitest\\delta", 500);
4193     create_file("msitest\\epsilon", 500);
4194     create_file("msitest\\zeta", 500);
4195     create_file("msitest\\iota", 500);
4196     create_file("msitest\\eta", 500);
4197     create_file("msitest\\kappa", 500);
4198     create_file("msitest\\lambda", 500);
4199     create_file("msitest\\mu", 500);
4200 
4201     create_database(msifile, is_tables, ARRAY_SIZE(is_tables));
4202 
4203     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4204 
4205     r = MsiInstallProductA(msifile, NULL);
4206     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4207     {
4208         skip("Not enough rights to perform tests\n");
4209         goto error;
4210     }
4211     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4212     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4213     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4214     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4215     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4216     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4217     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4218     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4219     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4220     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4221     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4222     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4223     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4224     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4225 
4226     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
4227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4228     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4229     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4230     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4231     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4232     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4233     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
4234     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4235     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4236     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
4237     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4238     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4239     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4240     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4241 
4242     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
4243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4244     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4245     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4246     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4247     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4248     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4249     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4250     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4251     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4252     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4253     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4254     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4255     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4256     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4257 
4258     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
4259     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4260     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
4261     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4262     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4263     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
4264     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4265     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4266     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4267     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4268     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4269     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4270     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4271     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4272     ok(!delete_pf("msitest", FALSE), "Directory created\n");
4273 
4274 error:
4275     DeleteFileA(msifile);
4276     DeleteFileA("msitest\\alpha");
4277     DeleteFileA("msitest\\beta");
4278     DeleteFileA("msitest\\gamma");
4279     DeleteFileA("msitest\\theta");
4280     DeleteFileA("msitest\\delta");
4281     DeleteFileA("msitest\\epsilon");
4282     DeleteFileA("msitest\\zeta");
4283     DeleteFileA("msitest\\iota");
4284     DeleteFileA("msitest\\eta");
4285     DeleteFileA("msitest\\kappa");
4286     DeleteFileA("msitest\\lambda");
4287     DeleteFileA("msitest\\mu");
4288     RemoveDirectoryA("msitest");
4289 }
4290 
4291 static const struct sourcepathmap
4292 {
4293     BOOL sost; /* shortone\shorttwo */
4294     BOOL solt; /* shortone\longtwo */
4295     BOOL lost; /* longone\shorttwo */
4296     BOOL lolt; /* longone\longtwo */
4297     BOOL soste; /* shortone\shorttwo source exists */
4298     BOOL solte; /* shortone\longtwo source exists */
4299     BOOL loste; /* longone\shorttwo source exists */
4300     BOOL lolte; /* longone\longtwo source exists */
4301     UINT err;
4302     DWORD size;
4303 } spmap[256] =
4304 {
4305     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4306     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4307     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4308     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4309     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4310     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4311     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4312     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4313     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4314     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4315     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4316     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4317     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4318     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4319     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4320     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4321     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4322     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4323     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4324     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4325     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4326     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4327     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4328     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4329     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4330     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4331     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4332     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4333     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4334     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4335     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4336     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4337     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4338     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4339     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4340     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4341     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4342     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4343     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4344     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4345     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4346     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4347     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4348     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4349     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4350     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4351     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4352     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4353     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4354     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4355     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4356     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4357     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4358     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4359     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4360     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4361     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4362     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4363     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4364     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4365     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4366     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4367     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4368     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4369     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4370     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4371     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4372     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4373     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4374     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4375     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4376     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4377     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4378     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4379     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4380     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4381     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4382     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4383     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4384     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4385     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4386     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4387     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4388     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4389     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4390     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4391     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4392     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4393     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4394     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4395     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4396     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4397     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4398     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4399     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4400     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4401     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4402     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4403     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4404     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4405     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4406     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4407     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4408     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4409     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4410     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4411     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4412     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4413     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4414     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4415     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4416     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4417     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4418     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4419     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4420     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4421     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4422     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4423     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4424     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4425     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4426     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4427     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4428     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4429     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4430     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4431     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4432     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4433     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4434     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4435     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4436     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4437     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4438     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4439     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4440     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4441     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4442     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4443     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4444     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4445     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4446     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4447     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4448     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4449     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4450     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4451     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4452     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4453     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4454     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4455     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4456     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4457     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4458     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4459     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4460     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4461     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4462     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4463     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4464     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4465     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4466     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4467     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4468     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4469     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4470     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4471     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4472     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4473     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4474     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4475     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4476     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4477     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4478     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4479     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4480     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4481     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4482     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4483     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4484     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4485     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4486     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4487     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4488     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4489     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4490     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4491     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4492     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4493     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4494     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4495     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4496     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4497     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4498     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4499     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4500     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4501     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4502     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4503     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4504     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4505     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4506     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4507     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4508     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4509     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4510     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4511     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4512     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4513     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4514     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4515     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4516     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4517     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4518     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4519     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4520     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4521     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4522     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4523     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4524     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4525     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4526     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4527     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4528     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4529     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4530     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4531     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4532     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4533     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4534     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4535     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4536     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4537     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4538     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4539     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4540     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4541     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4542     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4543     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4544     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4545     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4546     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4547     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4548     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4549     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4550     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4551     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4552     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4553     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4554     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4555     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4556     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4557     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4558     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4559     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4560     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4561 };
4562 
get_pf_file_size(LPCSTR file)4563 static DWORD get_pf_file_size(LPCSTR file)
4564 {
4565     CHAR path[MAX_PATH];
4566     HANDLE hfile;
4567     DWORD size;
4568 
4569     lstrcpyA(path, PROG_FILES_DIR);
4570     lstrcatA(path, "\\");
4571     lstrcatA(path, file);
4572 
4573     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
4574     if (hfile == INVALID_HANDLE_VALUE)
4575         return INVALID_FILE_SIZE;
4576 
4577     size = GetFileSize(hfile, NULL);
4578     CloseHandle(hfile);
4579     return size;
4580 }
4581 
test_sourcepath(void)4582 static void test_sourcepath(void)
4583 {
4584     UINT r, i;
4585 
4586     if (!winetest_interactive)
4587     {
4588         skip("Run in interactive mode to run source path tests.\n");
4589         return;
4590     }
4591 
4592     create_database(msifile, sp_tables, ARRAY_SIZE(sp_tables));
4593 
4594     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4595 
4596     for (i = 0; i < ARRAY_SIZE(spmap); i++)
4597     {
4598         if (spmap[i].sost)
4599         {
4600             CreateDirectoryA("shortone", NULL);
4601             CreateDirectoryA("shortone\\shorttwo", NULL);
4602         }
4603 
4604         if (spmap[i].solt)
4605         {
4606             CreateDirectoryA("shortone", NULL);
4607             CreateDirectoryA("shortone\\longtwo", NULL);
4608         }
4609 
4610         if (spmap[i].lost)
4611         {
4612             CreateDirectoryA("longone", NULL);
4613             CreateDirectoryA("longone\\shorttwo", NULL);
4614         }
4615 
4616         if (spmap[i].lolt)
4617         {
4618             CreateDirectoryA("longone", NULL);
4619             CreateDirectoryA("longone\\longtwo", NULL);
4620         }
4621 
4622         if (spmap[i].soste)
4623             create_file("shortone\\shorttwo\\augustus", 50);
4624         if (spmap[i].solte)
4625             create_file("shortone\\longtwo\\augustus", 100);
4626         if (spmap[i].loste)
4627             create_file("longone\\shorttwo\\augustus", 150);
4628         if (spmap[i].lolte)
4629             create_file("longone\\longtwo\\augustus", 200);
4630 
4631         r = MsiInstallProductA(msifile, NULL);
4632         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
4633         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
4634            "%u: Expected %lu, got %lu\n", i, spmap[i].size,
4635            get_pf_file_size("msitest\\augustus"));
4636 
4637         if (r == ERROR_SUCCESS)
4638         {
4639             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
4640             ok(delete_pf("msitest", FALSE), "%d: Directory not created\n", i);
4641         }
4642         else
4643         {
4644             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
4645             todo_wine ok(!delete_pf("msitest", FALSE), "%d: Directory installed\n", i);
4646         }
4647 
4648         DeleteFileA("shortone\\shorttwo\\augustus");
4649         DeleteFileA("shortone\\longtwo\\augustus");
4650         DeleteFileA("longone\\shorttwo\\augustus");
4651         DeleteFileA("longone\\longtwo\\augustus");
4652         RemoveDirectoryA("shortone\\shorttwo");
4653         RemoveDirectoryA("shortone\\longtwo");
4654         RemoveDirectoryA("longone\\shorttwo");
4655         RemoveDirectoryA("longone\\longtwo");
4656         RemoveDirectoryA("shortone");
4657         RemoveDirectoryA("longone");
4658     }
4659 
4660     DeleteFileA(msifile);
4661 }
4662 
test_missingcomponent(void)4663 static void test_missingcomponent(void)
4664 {
4665     UINT r;
4666 
4667     if (!is_process_elevated())
4668     {
4669         skip("process is limited\n");
4670         return;
4671     }
4672 
4673     CreateDirectoryA("msitest", NULL);
4674     create_file("msitest\\hydrogen", 500);
4675     create_file("msitest\\helium", 500);
4676     create_file("msitest\\lithium", 500);
4677     create_file("beryllium", 500);
4678 
4679     create_database(msifile, mcp_tables, ARRAY_SIZE(mcp_tables));
4680 
4681     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4682 
4683     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
4684     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4685     {
4686         skip("Not enough rights to perform tests\n");
4687         goto error;
4688     }
4689     else if (r == ERROR_INSTALL_FAILURE)
4690     {
4691         win_skip("broken result\n");
4692         goto error;
4693     }
4694     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4695     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4696     ok(pf_exists("msitest\\helium"), "File not installed\n");
4697     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4698     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
4699     ok(pf_exists("msitest"), "File not installed\n");
4700 
4701     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
4702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4703     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
4704     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
4705     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
4706     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
4707     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
4708 
4709 error:
4710     DeleteFileA(msifile);
4711     DeleteFileA("msitest\\hydrogen");
4712     DeleteFileA("msitest\\helium");
4713     DeleteFileA("msitest\\lithium");
4714     DeleteFileA("beryllium");
4715     RemoveDirectoryA("msitest");
4716 }
4717 
test_sourcedirprop(void)4718 static void test_sourcedirprop(void)
4719 {
4720     UINT r;
4721     CHAR props[MAX_PATH + 18];
4722 
4723     if (!is_process_elevated())
4724     {
4725         skip("process is limited\n");
4726         return;
4727     }
4728 
4729     CreateDirectoryA("msitest", NULL);
4730     create_file("msitest\\augustus", 500);
4731 
4732     create_database(msifile, ca51_tables, ARRAY_SIZE(ca51_tables));
4733 
4734     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4735 
4736     r = MsiInstallProductA(msifile, NULL);
4737     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4738     {
4739         skip("Not enough rights to perform tests\n");
4740         goto error;
4741     }
4742     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4743     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4744     ok(delete_pf("msitest", FALSE), "Directory created\n");
4745 
4746     DeleteFileA("msitest\\augustus");
4747     RemoveDirectoryA("msitest");
4748 
4749     CreateDirectoryA("altsource", NULL);
4750     CreateDirectoryA("altsource\\msitest", NULL);
4751     create_file("altsource\\msitest\\augustus", 500);
4752 
4753     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
4754 
4755     r = MsiInstallProductA(msifile, props);
4756     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4757     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4758     ok(delete_pf("msitest", FALSE), "Directory created\n");
4759 
4760     DeleteFileA("altsource\\msitest\\augustus");
4761     RemoveDirectoryA("altsource\\msitest");
4762     RemoveDirectoryA("altsource");
4763 
4764 error:
4765     DeleteFileA("msitest\\augustus");
4766     RemoveDirectoryA("msitest");
4767     DeleteFileA(msifile);
4768 }
4769 
test_adminimage(void)4770 static void test_adminimage(void)
4771 {
4772     UINT r;
4773 
4774     if (!is_process_elevated())
4775     {
4776         skip("process is limited\n");
4777         return;
4778     }
4779 
4780     CreateDirectoryA("msitest", NULL);
4781     CreateDirectoryA("msitest\\first", NULL);
4782     CreateDirectoryA("msitest\\second", NULL);
4783     CreateDirectoryA("msitest\\cabout", NULL);
4784     CreateDirectoryA("msitest\\cabout\\new", NULL);
4785     create_file("msitest\\one.txt", 100);
4786     create_file("msitest\\first\\two.txt", 100);
4787     create_file("msitest\\second\\three.txt", 100);
4788     create_file("msitest\\cabout\\four.txt", 100);
4789     create_file("msitest\\cabout\\new\\five.txt", 100);
4790     create_file("msitest\\filename", 100);
4791 
4792     create_database_wordcount(msifile, ai_tables, ARRAY_SIZE(ai_tables),
4793                               100, msidbSumInfoSourceTypeAdminImage, ";1033",
4794                               "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
4795 
4796     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4797 
4798     r = MsiInstallProductA(msifile, NULL);
4799     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4800     {
4801         skip("Not enough rights to perform tests\n");
4802         goto error;
4803     }
4804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4805 
4806     delete_pf_files();
4807 
4808     create_file("four.txt", 100);
4809     create_file("five.txt", 100);
4810     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
4811     create_database_wordcount(msifile, ai2_tables, ARRAY_SIZE(ai2_tables),
4812                               100, msidbSumInfoSourceTypeAdminImage|msidbSumInfoSourceTypeCompressed,
4813                               ";1033", "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
4814 
4815     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4816 
4817     r = MsiInstallProductA(msifile, NULL);
4818     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4819 
4820     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
4821     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
4822     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
4823     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
4824     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4825 
4826 error:
4827     DeleteFileA("msifile");
4828     DeleteFileA("msitest\\cabout\\new\\five.txt");
4829     DeleteFileA("msitest\\cabout\\four.txt");
4830     DeleteFileA("msitest\\second\\three.txt");
4831     DeleteFileA("msitest\\first\\two.txt");
4832     DeleteFileA("msitest\\one.txt");
4833     DeleteFileA("msitest\\filename");
4834     RemoveDirectoryA("msitest\\cabout\\new");
4835     RemoveDirectoryA("msitest\\cabout");
4836     RemoveDirectoryA("msitest\\second");
4837     RemoveDirectoryA("msitest\\first");
4838     RemoveDirectoryA("msitest");
4839 }
4840 
test_propcase(void)4841 static void test_propcase(void)
4842 {
4843     UINT r;
4844 
4845     if (!is_process_elevated())
4846     {
4847         skip("process is limited\n");
4848         return;
4849     }
4850 
4851     CreateDirectoryA("msitest", NULL);
4852     create_file("msitest\\augustus", 500);
4853 
4854     create_database(msifile, pc_tables, ARRAY_SIZE(pc_tables));
4855 
4856     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4857 
4858     r = MsiInstallProductA(msifile, "MyProp=42");
4859     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4860     {
4861         skip("Not enough rights to perform tests\n");
4862         goto error;
4863     }
4864     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4865     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4866     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4867 
4868     r = MsiInstallProductA(msifile, "Prop1=\"Copyright \"\"My Company\"\" 2015\" MyProp=42");
4869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4870     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4871     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4872 
4873     r = MsiInstallProductA(msifile, "Prop1=\"\"\"install.exe\"\" /Install\" MyProp=\"42\"");
4874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4875     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4876     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4877 
4878 error:
4879     DeleteFileA(msifile);
4880     DeleteFileA("msitest\\augustus");
4881     RemoveDirectoryA("msitest");
4882 }
4883 
test_int_widths(void)4884 static void test_int_widths( void )
4885 {
4886     static const char int0[] = "int0\ni0\nint0\tint0\n1";
4887     static const char int1[] = "int1\ni1\nint1\tint1\n1";
4888     static const char int2[] = "int2\ni2\nint2\tint2\n1";
4889     static const char int3[] = "int3\ni3\nint3\tint3\n1";
4890     static const char int4[] = "int4\ni4\nint4\tint4\n1";
4891     static const char int5[] = "int5\ni5\nint5\tint5\n1";
4892     static const char int8[] = "int8\ni8\nint8\tint8\n1";
4893     static const struct
4894     {
4895         const char  *data;
4896         unsigned int size;
4897         UINT         ret;
4898     }
4899     tests[] =
4900     {
4901         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
4902         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
4903         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
4904         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
4905         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
4906         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
4907         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
4908     };
4909     WCHAR tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
4910     MSIHANDLE db;
4911     UINT r, i;
4912 
4913     GetTempPathW(MAX_PATH, tmpdir);
4914     CreateDirectoryW(tmpdir, NULL);
4915 
4916     lstrcpyW(msitable, tmpdir);
4917     lstrcatW(msitable, L"\\msitable.idt");
4918 
4919     lstrcpyW(msidb, tmpdir);
4920     lstrcatW(msidb, L"\\msitest.msi");
4921 
4922     r = MsiOpenDatabaseW(msidb, MSIDBOPEN_CREATE, &db);
4923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4924 
4925     for (i = 0; i < ARRAY_SIZE(tests); i++)
4926     {
4927         DWORD count;
4928         HANDLE handle = CreateFileW(msitable, GENERIC_WRITE, 0, NULL,
4929                                     CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
4930         WriteFile(handle, tests[i].data, tests[i].size, &count, NULL);
4931         CloseHandle(handle);
4932 
4933         r = MsiDatabaseImportW(db, tmpdir, L"msitable.idt");
4934         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
4935 
4936         r = MsiDatabaseCommit(db);
4937         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4938         DeleteFileW(msitable);
4939     }
4940 
4941     MsiCloseHandle(db);
4942     DeleteFileW(msidb);
4943     RemoveDirectoryW(tmpdir);
4944 }
4945 
test_shortcut(void)4946 static void test_shortcut(void)
4947 {
4948     UINT r;
4949     HRESULT hr;
4950 
4951     if (!is_process_elevated())
4952     {
4953         skip("process is limited\n");
4954         return;
4955     }
4956 
4957     create_test_files();
4958     create_database(msifile, sc_tables, ARRAY_SIZE(sc_tables));
4959 
4960     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4961 
4962     r = MsiInstallProductA(msifile, NULL);
4963     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4964     {
4965         skip("Not enough rights to perform tests\n");
4966         goto error;
4967     }
4968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4969 
4970     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
4971     ok(SUCCEEDED(hr), "CoInitialize failed %#lx\n", hr);
4972 
4973     r = MsiInstallProductA(msifile, NULL);
4974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4975 
4976     CoUninitialize();
4977 
4978     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
4979     ok(SUCCEEDED(hr), "CoInitialize failed %#lx\n", hr);
4980 
4981     r = MsiInstallProductA(msifile, NULL);
4982     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4983 
4984     CoUninitialize();
4985 
4986     while (!delete_pf("msitest\\Shortcut.lnk", TRUE) && GetLastError() == ERROR_SHARING_VIOLATION) Sleep(1000);
4987     delete_pf_files();
4988 
4989 error:
4990     delete_test_files();
4991     DeleteFileA(msifile);
4992 }
4993 
test_preselected(void)4994 static void test_preselected(void)
4995 {
4996     UINT r;
4997 
4998     if (!is_process_elevated())
4999     {
5000         skip("process is limited\n");
5001         return;
5002     }
5003 
5004     create_test_files();
5005     create_database(msifile, ps_tables, ARRAY_SIZE(ps_tables));
5006 
5007     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5008 
5009     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
5010     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5011     {
5012         skip("Not enough rights to perform tests\n");
5013         goto error;
5014     }
5015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5016 
5017     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
5018     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
5019     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
5020     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
5021     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
5022     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
5023     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
5024     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
5025     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
5026     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5027     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5028 
5029     r = MsiInstallProductA(msifile, NULL);
5030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5031 
5032     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5033     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5034     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5035     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5036     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5037     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5038     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5039     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5040     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5041     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
5042     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5043 
5044 error:
5045     delete_test_files();
5046     DeleteFileA(msifile);
5047 }
5048 
test_installed_prop(void)5049 static void test_installed_prop(void)
5050 {
5051     static const char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
5052     UINT r;
5053 
5054     if (!is_process_elevated())
5055     {
5056         skip("process is limited\n");
5057         return;
5058     }
5059 
5060     create_test_files();
5061     create_database(msifile, ip_tables, ARRAY_SIZE(ip_tables));
5062 
5063     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5064 
5065     r = MsiInstallProductA(msifile, "FULL=1");
5066     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5067     {
5068         skip("Not enough rights to perform tests\n");
5069         goto error;
5070     }
5071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5072 
5073     r = MsiInstallProductA(msifile, "FULL=1");
5074     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5075 
5076     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
5077     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5078 
5079     delete_pf_files();
5080 
5081     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5083 
5084 error:
5085     delete_test_files();
5086     DeleteFileA(msifile);
5087 }
5088 
test_allusers_prop(void)5089 static void test_allusers_prop(void)
5090 {
5091     UINT r;
5092 
5093     if (!is_process_elevated())
5094     {
5095         skip("process is limited\n");
5096         return;
5097     }
5098 
5099     create_test_files();
5100     create_database(msifile, aup_tables, ARRAY_SIZE(aup_tables));
5101 
5102     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5103 
5104     /* ALLUSERS property unset */
5105     r = MsiInstallProductA(msifile, "FULL=1");
5106     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5107     {
5108         skip("Not enough rights to perform tests\n");
5109         goto error;
5110     }
5111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5112 
5113     delete_pf_files();
5114 
5115     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5116     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5117 
5118     delete_test_files();
5119 
5120     create_test_files();
5121     create_database(msifile, aup2_tables, ARRAY_SIZE(aup2_tables));
5122 
5123     /* ALLUSERS property set to 1 */
5124     r = MsiInstallProductA(msifile, "FULL=1");
5125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5126 
5127     delete_pf_files();
5128 
5129     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5131 
5132     delete_test_files();
5133 
5134     create_test_files();
5135     create_database(msifile, aup3_tables, ARRAY_SIZE(aup3_tables));
5136 
5137     /* ALLUSERS property set to 2 */
5138     r = MsiInstallProductA(msifile, "FULL=1");
5139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5140 
5141     delete_pf_files();
5142 
5143     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5144     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5145 
5146     delete_test_files();
5147 
5148     create_test_files();
5149     create_database(msifile, aup4_tables, ARRAY_SIZE(aup4_tables));
5150 
5151     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
5152     r = MsiInstallProductA(msifile, "FULL=1");
5153     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5154 
5155 error:
5156     delete_test_files();
5157     DeleteFileA(msifile);
5158 }
5159 
5160 static const char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
5161 static const char rename_ops[]      = "PendingFileRenameOperations";
5162 
process_pending_renames(HKEY hkey)5163 static void process_pending_renames(HKEY hkey)
5164 {
5165     char *buf, *src, *dst, *buf2, *buf2ptr;
5166     DWORD size;
5167     LONG ret;
5168     BOOL found = FALSE;
5169 
5170     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
5171     ok(!ret, "RegQueryValueExA failed %ld\n", ret);
5172 
5173     buf = malloc(size + 1);
5174     buf2ptr = buf2 = calloc(1, size + 1);
5175 
5176     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
5177     buf[size] = 0;
5178     ok(!ret, "RegQueryValueExA failed %ld\n", ret);
5179     if (ret) return;
5180 
5181     for (src = buf; *src; src = dst + strlen(dst) + 1)
5182     {
5183         DWORD flags = MOVEFILE_COPY_ALLOWED;
5184         BOOL fileret;
5185 
5186         dst = src + strlen(src) + 1;
5187 
5188         if (!strstr(src, "msitest"))
5189         {
5190             lstrcpyA(buf2ptr, src);
5191             buf2ptr += strlen(src) + 1;
5192             lstrcpyA(buf2ptr, dst);
5193             buf2ptr += strlen(dst) + 1;
5194             continue;
5195         }
5196 
5197         found = TRUE;
5198 
5199         if (*dst == '!')
5200         {
5201             flags |= MOVEFILE_REPLACE_EXISTING;
5202             dst++;
5203         }
5204         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
5205         if (*dst)
5206         {
5207             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
5208             fileret = MoveFileExA(src, dst, flags);
5209             ok(fileret, "Failed to move file %s -> %s (%lu)\n", src, dst, GetLastError());
5210         }
5211         else
5212         {
5213             fileret = DeleteFileA(src);
5214             ok(fileret, "Failed to delete file %s (%lu)\n", src, GetLastError());
5215         }
5216     }
5217 
5218     ok(found, "Expected a 'msitest' entry\n");
5219 
5220     if (*buf2)
5221         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2ptr + 1 - buf2);
5222     else
5223         RegDeleteValueA(hkey, rename_ops);
5224 
5225     free(buf);
5226     free(buf2);
5227 }
5228 
file_matches_data(LPCSTR file,LPCSTR data)5229 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
5230 {
5231     DWORD len, data_len = strlen(data);
5232     HANDLE handle;
5233     char buf[128];
5234 
5235     handle = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
5236     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%lu)\n", file, GetLastError());
5237 
5238     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
5239     {
5240         CloseHandle(handle);
5241         return !memcmp(buf, data, data_len);
5242     }
5243     CloseHandle(handle);
5244     return FALSE;
5245 }
5246 
test_file_in_use(void)5247 static void test_file_in_use(void)
5248 {
5249     UINT r;
5250     HANDLE file;
5251     HKEY hkey;
5252     char path[MAX_PATH];
5253 
5254     if (!is_process_elevated())
5255     {
5256         skip("process is limited\n");
5257         return;
5258     }
5259 
5260     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
5261 
5262     CreateDirectoryA("msitest", NULL);
5263     create_file("msitest\\maximus", 500);
5264     create_database(msifile, fiu_tables, ARRAY_SIZE(fiu_tables));
5265 
5266     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5267 
5268     lstrcpyA(path, PROG_FILES_DIR);
5269     lstrcatA(path, "\\msitest");
5270     CreateDirectoryA(path, NULL);
5271 
5272     lstrcatA(path, "\\maximus");
5273     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
5274 
5275     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
5276     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5277     {
5278         skip("Not enough rights to perform tests\n");
5279         goto error;
5280     }
5281     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
5282     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
5283     CloseHandle(file);
5284     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
5285 
5286     process_pending_renames(hkey);
5287     RegCloseKey(hkey);
5288 
5289     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
5290     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
5291     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
5292 
5293     r = MsiInstallProductA(msifile, "REMOVE=ALL FULL=1");
5294     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5295 
5296 error:
5297     RegCloseKey(hkey);
5298 
5299     delete_pf("msitest\\maximus", TRUE);
5300     delete_pf("msitest", FALSE);
5301     DeleteFileA("msitest\\maximus");
5302     delete_test_files();
5303     DeleteFileA(msifile);
5304 }
5305 
test_file_in_use_cab(void)5306 static void test_file_in_use_cab(void)
5307 {
5308     UINT r;
5309     HANDLE file;
5310     HKEY hkey;
5311     char path[MAX_PATH];
5312 
5313     if (!is_process_elevated())
5314     {
5315         skip("process is limited\n");
5316         return;
5317     }
5318 
5319     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
5320 
5321     CreateDirectoryA("msitest", NULL);
5322     create_file("maximus", 500);
5323     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
5324     DeleteFileA("maximus");
5325 
5326     create_database(msifile, fiuc_tables, ARRAY_SIZE(fiuc_tables));
5327 
5328     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5329 
5330     lstrcpyA(path, PROG_FILES_DIR);
5331     lstrcatA(path, "\\msitest");
5332     CreateDirectoryA(path, NULL);
5333 
5334     lstrcatA(path, "\\maximus");
5335     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
5336 
5337     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
5338     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5339     {
5340         skip("Not enough rights to perform tests\n");
5341         goto error;
5342     }
5343     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
5344     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
5345     CloseHandle(file);
5346     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
5347 
5348     process_pending_renames(hkey);
5349     RegCloseKey(hkey);
5350 
5351     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
5352     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
5353     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
5354 
5355     r = MsiInstallProductA(msifile, "REMOVE=ALL FULL=1");
5356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5357 
5358 error:
5359     RegCloseKey(hkey);
5360 
5361     delete_pf("msitest\\maximus", TRUE);
5362     delete_pf("msitest", FALSE);
5363     DeleteFileA("msitest\\maximus");
5364     delete_cab_files();
5365     delete_test_files();
5366     DeleteFileA(msifile);
5367 }
5368 
test_feature_override(void)5369 static void test_feature_override(void)
5370 {
5371     UINT r;
5372     REGSAM access = KEY_ALL_ACCESS;
5373 
5374     if (!is_process_elevated())
5375     {
5376         skip("process is limited\n");
5377         return;
5378     }
5379 
5380     create_test_files();
5381     create_file("msitest\\override.txt", 1000);
5382     create_file("msitest\\preselected.txt", 1000);
5383     create_file("msitest\\notpreselected.txt", 1000);
5384     create_database(msifile, fo_tables, ARRAY_SIZE(fo_tables));
5385 
5386     if (is_wow64)
5387         access |= KEY_WOW64_64KEY;
5388 
5389     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5390 
5391     r = MsiInstallProductA(msifile, "ADDLOCAL=override");
5392     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5393     {
5394         skip("Not enough rights to perform tests\n");
5395         goto error;
5396     }
5397     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5398 
5399     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
5400     ok(!pf_exists("msitest\\preselected.txt"), "file installed\n");
5401     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
5402 
5403     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5405 
5406     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
5407 
5408     r = MsiInstallProductA(msifile, "preselect=1");
5409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5410 
5411     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
5412     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
5413     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
5414 
5415     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5417 
5418     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
5419     ok(!delete_pf("msitest\\preselected.txt", TRUE), "file not removed\n");
5420     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5421 
5422     r = MsiInstallProductA(msifile, NULL);
5423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5424 
5425     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
5426     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
5427     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
5428 
5429     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5431 
5432     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
5433     ok(!delete_pf("msitest\\preselected.txt", TRUE), "file not removed\n");
5434     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5435 
5436     RegDeleteKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", access, 0);
5437 
5438 error:
5439     DeleteFileA("msitest\\override.txt");
5440     DeleteFileA("msitest\\preselected.txt");
5441     DeleteFileA("msitest\\notpreselected.txt");
5442     delete_test_files();
5443     DeleteFileA(msifile);
5444 }
5445 
test_icon_table(void)5446 static void test_icon_table(void)
5447 {
5448     MSIHANDLE hdb = 0, record;
5449     LPCSTR query;
5450     UINT res;
5451     CHAR path[MAX_PATH];
5452     static const char prodcode[] = "{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}";
5453 
5454     if (!is_process_elevated())
5455     {
5456         skip("process is limited\n");
5457         return;
5458     }
5459 
5460     create_database(msifile, icon_base_tables, ARRAY_SIZE(icon_base_tables));
5461 
5462     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5463 
5464     res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb);
5465     ok(res == ERROR_SUCCESS, "failed to open db: %d\n", res);
5466 
5467     query = "CREATE TABLE `Icon` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL  PRIMARY KEY `Name`)";
5468     res = run_query( hdb, 0, query );
5469     ok(res == ERROR_SUCCESS, "Can't create Icon table: %d\n", res);
5470 
5471     create_file("icon.ico", 100);
5472     record = MsiCreateRecord(1);
5473     res = MsiRecordSetStreamA(record, 1, "icon.ico");
5474     ok(res == ERROR_SUCCESS, "Failed to add stream data to record: %d\n", res);
5475 
5476     query = "INSERT INTO `Icon` (`Name`, `Data`) VALUES ('testicon', ?)";
5477     res = run_query(hdb, record, query);
5478     ok(res == ERROR_SUCCESS, "Insert into Icon table failed: %d\n", res);
5479 
5480     res = MsiCloseHandle(record);
5481     ok(res == ERROR_SUCCESS, "Failed to close record handle: %d\n", res);
5482     DeleteFileA("icon.ico");
5483     res = MsiDatabaseCommit(hdb);
5484     ok(res == ERROR_SUCCESS, "Failed to commit database: %d\n", res);
5485     res = MsiCloseHandle(hdb);
5486     ok(res == ERROR_SUCCESS, "Failed to close database: %d\n", res);
5487 
5488     /* per-user */
5489     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
5490     if (res == ERROR_INSTALL_PACKAGE_REJECTED)
5491     {
5492         skip("Not enough rights to perform tests\n");
5493         DeleteFileA(msifile);
5494         return;
5495     }
5496     ok(res == ERROR_SUCCESS, "Failed to do per-user install: %d\n", res);
5497 
5498     lstrcpyA(path, APP_DATA_DIR);
5499     lstrcatA(path, "\\");
5500     lstrcatA(path, "Microsoft\\Installer\\");
5501     lstrcatA(path, prodcode);
5502     lstrcatA(path, "\\testicon");
5503     ok(file_exists(path), "Per-user icon file isn't where it's expected (%s)\n", path);
5504 
5505     res = MsiInstallProductA(msifile, "REMOVE=ALL FULL=1");
5506     ok(res == ERROR_SUCCESS, "Failed to uninstall per-user\n");
5507     ok(!file_exists(path), "Per-user icon file not removed (%s)\n", path);
5508 
5509     /* system-wide */
5510     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
5511     ok(res == ERROR_SUCCESS, "Failed to system-wide install: %d\n", res);
5512 
5513     lstrcpyA(path, WINDOWS_DIR);
5514     lstrcatA(path, "\\");
5515     lstrcatA(path, "Installer\\");
5516     lstrcatA(path, prodcode);
5517     lstrcatA(path, "\\testicon");
5518     ok(file_exists(path), "System-wide icon file isn't where it's expected (%s)\n", path);
5519 
5520     res = MsiInstallProductA(msifile, "REMOVE=ALL FULL=1");
5521     ok(res == ERROR_SUCCESS, "Failed to uninstall system-wide\n");
5522     ok(!file_exists(path), "System-wide icon file not removed (%s)\n", path);
5523 
5524     delete_pfmsitest_files();
5525     DeleteFileA(msifile);
5526 }
5527 
test_package_validation(void)5528 static void test_package_validation(void)
5529 {
5530     UINT r;
5531 
5532     if (!is_process_elevated())
5533     {
5534         skip("process is limited\n");
5535         return;
5536     }
5537 
5538     CreateDirectoryA("msitest", NULL);
5539     create_file("msitest\\maximus", 500);
5540     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel;1033");
5541 
5542     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5543 
5544     r = MsiInstallProductA(msifile, NULL);
5545     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5546     {
5547         skip("Not enough rights to perform tests\n");
5548         goto error;
5549     }
5550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5551     ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5552     ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5553 
5554     DeleteFileA(msifile);
5555     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "Intel,9999;9999");
5556 
5557     r = MsiInstallProductA(msifile, NULL);
5558     ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r);
5559 
5560     DeleteFileA(msifile);
5561     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "Intel,1033;9999");
5562 
5563     r = MsiInstallProductA(msifile, NULL);
5564     ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r);
5565 
5566     DeleteFileA(msifile);
5567     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "Intel,9999;1033");
5568 
5569     r = MsiInstallProductA(msifile, NULL);
5570     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5571     ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5572     ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5573 
5574     DeleteFileA(msifile);
5575     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "Intel64,9999;1033");
5576 
5577     r = MsiInstallProductA(msifile, NULL);
5578     ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
5579 
5580     DeleteFileA(msifile);
5581     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "Intel32,1033;1033");
5582 
5583     r = MsiInstallProductA(msifile, NULL);
5584     ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
5585 
5586     DeleteFileA(msifile);
5587     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "Intel32,9999;1033");
5588 
5589     r = MsiInstallProductA(msifile, NULL);
5590     ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
5591 
5592     DeleteFileA(msifile);
5593     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel;9999");
5594 
5595     r = MsiInstallProductA(msifile, NULL);
5596     ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r);
5597     ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
5598     ok(!delete_pf("msitest", FALSE), "directory exists\n");
5599 
5600     if (GetSystemDefaultLangID() == MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ))
5601     {
5602         DeleteFileA(msifile);
5603         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel;9");
5604         r = MsiInstallProductA(msifile, NULL);
5605         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5606         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5607         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5608 
5609         DeleteFileA(msifile);
5610         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel;1024");
5611         r = MsiInstallProductA(msifile, NULL);
5612         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5613         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5614         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5615     }
5616 
5617     DeleteFileA(msifile);
5618     create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel32;0");
5619 
5620     r = MsiInstallProductA(msifile, NULL);
5621     ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
5622     ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
5623     ok(!delete_pf("msitest", FALSE), "directory exists\n");
5624 
5625     if (is_64bit && !is_wow64)
5626     {
5627         DeleteFileA(msifile);
5628         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel;0");
5629 
5630         r = MsiInstallProductA(msifile, NULL);
5631         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5632         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5633         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5634 
5635         DeleteFileA(msifile);
5636         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "x64;0");
5637 
5638         r = MsiInstallProductA(msifile, NULL);
5639         ok(r == ERROR_INSTALL_PACKAGE_INVALID, "Expected ERROR_INSTALL_PACKAGE_INVALID, got %u\n", r);
5640         ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
5641         ok(!delete_pf("msitest", FALSE), "directory exists\n");
5642 
5643         DeleteFileA(msifile);
5644         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "x64;0");
5645 
5646         r = MsiInstallProductA(msifile, NULL);
5647         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5648         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5649         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5650     }
5651     else if (is_wow64)
5652     {
5653         DeleteFileA(msifile);
5654         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel;0");
5655 
5656         r = MsiInstallProductA(msifile, NULL);
5657         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5658         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5659         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5660 
5661         DeleteFileA(msifile);
5662         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "x64;0");
5663 
5664         r = MsiInstallProductA(msifile, NULL);
5665         ok(r == ERROR_INSTALL_PACKAGE_INVALID, "Expected ERROR_INSTALL_PACKAGE_INVALID, got %u\n", r);
5666         ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
5667         ok(!delete_pf("msitest", FALSE), "directory exists\n");
5668 
5669         DeleteFileA(msifile);
5670         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "x64;0");
5671 
5672         r = MsiInstallProductA(msifile, NULL);
5673         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5674         ok(delete_pf("msitest\\maximus", TRUE), "file exists\n");
5675         ok(delete_pf("msitest", FALSE), "directory exists\n");
5676     }
5677     else
5678     {
5679         DeleteFileA(msifile);
5680         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Intel;0");
5681 
5682         r = MsiInstallProductA(msifile, NULL);
5683         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5684         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5685         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5686 
5687         DeleteFileA(msifile);
5688         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "Alpha,Beta,Intel;0");
5689 
5690         r = MsiInstallProductA(msifile, NULL);
5691         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5692         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
5693         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
5694 
5695         DeleteFileA(msifile);
5696         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 100, "x64;0");
5697 
5698         r = MsiInstallProductA(msifile, NULL);
5699         ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
5700         ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
5701         ok(!delete_pf("msitest", FALSE), "directory exists\n");
5702 
5703         DeleteFileA(msifile);
5704         create_database_template(msifile, pv_tables, ARRAY_SIZE(pv_tables), 200, "x64;0");
5705 
5706         r = MsiInstallProductA(msifile, NULL);
5707         ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
5708         ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
5709         ok(!delete_pf("msitest", FALSE), "directory exists\n");
5710     }
5711 
5712 error:
5713     /* Delete the files in the temp (current) folder */
5714     DeleteFileA(msifile);
5715     DeleteFileA("msitest\\maximus");
5716     RemoveDirectoryA("msitest");
5717 }
5718 
test_upgrade_code(void)5719 static void test_upgrade_code(void)
5720 {
5721     UINT r;
5722 
5723     if (!is_process_elevated())
5724     {
5725         skip("process is limited\n");
5726         return;
5727     }
5728 
5729     CreateDirectoryA("msitest", NULL);
5730     create_file("msitest\\upgradecode.txt", 1000);
5731     create_database(msifile, uc_tables, ARRAY_SIZE(uc_tables));
5732 
5733     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5734 
5735     r = MsiInstallProductA(msifile, NULL);
5736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5737 
5738     ok(pf_exists("msitest\\upgradecode.txt"), "file not installed\n");
5739 
5740     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5741     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5742 
5743     ok(!delete_pf("msitest\\upgradecode.txt", TRUE), "file not removed\n");
5744     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5745 
5746     DeleteFileA("msitest\\upgradecode.txt");
5747     RemoveDirectoryA("msitest");
5748     DeleteFileA(msifile);
5749 }
5750 
test_mixed_package(void)5751 static void test_mixed_package(void)
5752 {
5753     UINT r;
5754     LONG res;
5755     HKEY hkey;
5756     char value[MAX_PATH];
5757     DWORD size;
5758 
5759     if (!is_process_elevated())
5760     {
5761         skip("process is limited\n");
5762         return;
5763     }
5764     if (!is_wow64 && !is_64bit)
5765     {
5766         skip("this test must be run on 64-bit\n");
5767         return;
5768     }
5769     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5770     create_database_template(msifile, mixed_tables, ARRAY_SIZE(mixed_tables), 200, "x64;1033");
5771 
5772     r = MsiInstallProductA(msifile, NULL);
5773     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5774     {
5775         skip("Not enough rights to perform tests\n");
5776         goto error;
5777     }
5778     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5779 
5780     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5781     ok(!res, "can't open 32-bit component key, got %ld\n", res);
5782     res = RegQueryValueExA(hkey, "test1", NULL, NULL, NULL, NULL);
5783     ok(!res, "expected RegQueryValueEx to succeed, got %ld\n", res);
5784     res = RegQueryValueExA(hkey, "test2", NULL, NULL, NULL, NULL);
5785     ok(res, "expected RegQueryValueEx to fail, got %ld\n", res);
5786     RegCloseKey(hkey);
5787 
5788     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5789     ok(!res, "can't open 64-bit component key, got %ld\n", res);
5790     res = RegQueryValueExA(hkey, "test1", NULL, NULL, NULL, NULL);
5791     ok(res, "expected RegQueryValueEx to fail, got %ld\n", res);
5792     res = RegQueryValueExA(hkey, "test2", NULL, NULL, NULL, NULL);
5793     ok(!res, "expected RegQueryValueEx to succeed, got %ld\n", res);
5794     RegCloseKey(hkey);
5795 
5796     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5797                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32",
5798                         0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5799     ok(res == ERROR_SUCCESS, "can't open 32-bit CLSID key, got %ld\n", res);
5800     if (res == ERROR_SUCCESS) {
5801         size = sizeof(value);
5802         res = RegQueryValueExA(hkey, "", NULL, NULL, (LPBYTE)value, &size);
5803         ok(!strcmp(value, "winetest32.dll"), "got %s\n", value);
5804         RegCloseKey(hkey);
5805     }
5806 
5807     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5808                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32",
5809                         0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5810     ok(res == ERROR_SUCCESS, "can't open 64-bit CLSID key, got %ld\n", res);
5811     if (res == ERROR_SUCCESS) {
5812         size = sizeof(value);
5813         res = RegQueryValueExA(hkey, "", NULL, NULL, (LPBYTE)value, &size);
5814         ok(!strcmp(value, "winetest64.dll"), "got %s\n", value);
5815         RegCloseKey(hkey);
5816     }
5817 
5818     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5820 
5821     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5822     ok(res == ERROR_FILE_NOT_FOUND, "32-bit component key not removed\n");
5823 
5824     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5825     ok(res == ERROR_FILE_NOT_FOUND, "64-bit component key not removed\n");
5826 
5827     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5828                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}",
5829                         0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5830     ok(res == ERROR_FILE_NOT_FOUND, "32-bit CLSID key not removed\n");
5831 
5832     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5833                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}",
5834                         0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5835     ok(res == ERROR_FILE_NOT_FOUND, "64-bit CLSID key not removed\n");
5836 
5837     DeleteFileA( msifile );
5838     create_database_template(msifile, mixed_tables, ARRAY_SIZE(mixed_tables), 200, "Intel;1033");
5839 
5840     r = MsiInstallProductA(msifile, NULL);
5841     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5842 
5843     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5844     ok(!res, "can't open 32-bit component key, got %ld\n", res);
5845     res = RegQueryValueExA(hkey, "test1", NULL, NULL, NULL, NULL);
5846     ok(!res, "expected RegQueryValueEx to succeed, got %ld\n", res);
5847     res = RegQueryValueExA(hkey, "test2", NULL, NULL, NULL, NULL);
5848     ok(res, "expected RegQueryValueEx to fail, got %ld\n", res);
5849     RegCloseKey(hkey);
5850 
5851     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5852     ok(!res, "can't open 64-bit component key, got %ld\n", res);
5853     res = RegQueryValueExA(hkey, "test1", NULL, NULL, NULL, NULL);
5854     ok(res, "expected RegQueryValueEx to fail, got %ld\n", res);
5855     res = RegQueryValueExA(hkey, "test2", NULL, NULL, NULL, NULL);
5856     ok(!res, "expected RegQueryValueEx to succeed, got %ld\n", res);
5857     RegCloseKey(hkey);
5858 
5859     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5860                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32",
5861                         0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5862     ok(res == ERROR_SUCCESS, "can't open 32-bit CLSID key, got %ld\n", res);
5863     if (res == ERROR_SUCCESS) {
5864         size = sizeof(value);
5865         res = RegQueryValueExA(hkey, "", NULL, NULL, (LPBYTE)value, &size);
5866         ok(!strcmp(value, "winetest32.dll"), "got %s\n", value);
5867         RegCloseKey(hkey);
5868     }
5869 
5870     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5871                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32",
5872                         0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5873     ok(res == ERROR_SUCCESS, "can't open 64-bit CLSID key, got %ld\n", res);
5874     if (res == ERROR_SUCCESS) {
5875         size = sizeof(value);
5876         res = RegQueryValueExA(hkey, "", NULL, NULL, (LPBYTE)value, &size);
5877         ok(!strcmp(value, "winetest64.dll"), "got %s\n", value);
5878         RegCloseKey(hkey);
5879     }
5880 
5881     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5882     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5883 
5884     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5885     ok(res == ERROR_FILE_NOT_FOUND, "32-bit component key not removed\n");
5886 
5887     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5888     ok(res == ERROR_FILE_NOT_FOUND, "64-bit component key not removed\n");
5889 
5890     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5891                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}",
5892                         0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey);
5893     ok(res == ERROR_FILE_NOT_FOUND, "32-bit CLSID key not removed\n");
5894 
5895     res = RegOpenKeyExA(HKEY_CLASSES_ROOT,
5896                         "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}",
5897                         0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey);
5898     ok(res == ERROR_FILE_NOT_FOUND, "64-bit CLSID key not removed\n");
5899 
5900 error:
5901     DeleteFileA( msifile );
5902 }
5903 
test_volume_props(void)5904 static void test_volume_props(void)
5905 {
5906     UINT r;
5907 
5908     if (!is_process_elevated())
5909     {
5910         skip("process is limited\n");
5911         return;
5912     }
5913     CreateDirectoryA("msitest", NULL);
5914     create_file("msitest\\volumeprop.txt", 1000);
5915     create_database(msifile, vp_tables, ARRAY_SIZE(vp_tables));
5916 
5917     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5918 
5919     r = MsiInstallProductA(msifile, NULL);
5920     ok(r == ERROR_SUCCESS, "got %u\n", r);
5921 
5922     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5923     ok(r == ERROR_SUCCESS, "got %u\n", r);
5924 
5925     DeleteFileA("msitest\\volumeprop.txt");
5926     RemoveDirectoryA("msitest");
5927     DeleteFileA(msifile);
5928 }
5929 
test_shared_component(void)5930 static void test_shared_component(void)
5931 {
5932     UINT r;
5933 
5934     if (!is_process_elevated())
5935     {
5936         skip("process is limited\n");
5937         return;
5938     }
5939     CreateDirectoryA("msitest", NULL);
5940     create_file("msitest\\sharedcomponent.txt", 1000);
5941     create_database_wordcount(msifile, shc_tables, ARRAY_SIZE(shc_tables),
5942                               100, 0, ";", "{A8826420-FD72-4E61-9E15-C1944CF4CBE1}");
5943     create_database_wordcount(msifile2, shc2_tables, ARRAY_SIZE(shc2_tables),
5944                               100, 0, ";", "{A8B50B30-0E8A-4ACD-B3CF-1A5DC58B2739}");
5945 
5946     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5947 
5948     r = MsiInstallProductA(msifile, NULL);
5949     ok(r == ERROR_SUCCESS, "got %u\n", r);
5950 
5951     ok(pf_exists("msitest\\sharedcomponent.txt"), "file not installed\n");
5952 
5953     r = MsiInstallProductA(msifile2, NULL);
5954     ok(r == ERROR_SUCCESS, "got %u\n", r);
5955 
5956     ok(pf_exists("msitest\\sharedcomponent.txt"), "file not installed\n");
5957 
5958     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5959     ok(r == ERROR_SUCCESS, "got %u\n", r);
5960 
5961     ok(pf_exists("msitest\\sharedcomponent.txt"), "file removed\n");
5962 
5963     r = MsiInstallProductA(msifile2, "REMOVE=ALL");
5964     ok(r == ERROR_SUCCESS, "got %u\n", r);
5965 
5966     ok(!pf_exists("msitest\\sharedcomponent.txt"), "file not removed\n");
5967 
5968     DeleteFileA("msitest\\sharedcomponent.txt");
5969     RemoveDirectoryA("msitest");
5970     DeleteFileA(msifile);
5971     DeleteFileA(msifile2);
5972 }
5973 
test_remove_upgrade_code(void)5974 static void test_remove_upgrade_code(void)
5975 {
5976     UINT r;
5977     LONG res;
5978     HKEY hkey;
5979     REGSAM access = KEY_ALL_ACCESS;
5980     DWORD type, size;
5981     char buf[1];
5982 
5983     if (!is_process_elevated())
5984     {
5985         skip( "process is limited\n" );
5986         return;
5987     }
5988     if (is_wow64) access |= KEY_WOW64_64KEY;
5989 
5990     create_test_files();
5991     create_database( msifile, icon_base_tables, ARRAY_SIZE( icon_base_tables ));
5992 
5993     MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
5994 
5995     r = MsiInstallProductA( msifile, "FULL=1" );
5996     ok(r == ERROR_SUCCESS, "got %u\n", r);
5997 
5998     res = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
5999         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2",
6000         0, access, &hkey );
6001     ok( res == ERROR_SUCCESS, "got %ld\n", res );
6002 
6003     type = 0xdeadbeef;
6004     buf[0] = 0x55;
6005     size = sizeof(buf);
6006     res = RegQueryValueExA( hkey, "94A88FD7F6998CE40A22FB59F6B9C2BB", NULL, &type, (BYTE *)buf, &size );
6007     ok( res == ERROR_SUCCESS, "got %ld\n", res );
6008     ok( type == REG_SZ, "got %lu\n", type );
6009     ok( size == 1, "got %lu\n", size );
6010     ok( !buf[0], "wrong data\n" );
6011     RegCloseKey( hkey );
6012 
6013     r = MsiInstallProductA( msifile, "REMOVE=ALL" );
6014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6015 
6016     res = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
6017         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2",
6018         0, access, &hkey );
6019     ok( res == ERROR_FILE_NOT_FOUND, "got %ld\n", res );
6020 
6021     RemoveDirectoryA( "msitest" );
6022     DeleteFileA( msifile );
6023 }
6024 
test_feature_tree(void)6025 static void test_feature_tree(void)
6026 {
6027     UINT r;
6028 
6029     if (!is_process_elevated())
6030     {
6031         skip( "process is limited\n" );
6032         return;
6033     }
6034 
6035     create_file( "msitest\\featuretree.txt", 1000 );
6036     create_database( msifile, ft_tables, ARRAY_SIZE( ft_tables ));
6037 
6038     MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
6039 
6040     r = MsiInstallProductA( msifile, "INSTALLTYPE=\"0\"" );
6041     ok( r == ERROR_INSTALL_FAILURE, "got %u\n", r );
6042 
6043     r = MsiInstallProductA( msifile, "INSTALLTYPE=\"1\"" );
6044     ok( r == ERROR_SUCCESS, "got %u\n", r );
6045 
6046     r = MsiInstallProductA( msifile, "REMOVE=ALL" );
6047     ok( r == ERROR_SUCCESS, "got %u\n", r );
6048 
6049     DeleteFileA( "msitest\\featuretree.txt" );
6050     RemoveDirectoryA( "msitest" );
6051     DeleteFileA( msifile );
6052 }
6053 
check_file_matches(const char * filename,const char * text)6054 static void check_file_matches(const char *filename, const char *text)
6055 {
6056     char buffer[200];
6057     HANDLE file;
6058     DWORD size;
6059 
6060     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
6061     ReadFile(file, buffer, sizeof(buffer), &size, NULL);
6062     ok(size == strlen(text) && !memcmp(buffer, text, size), "got %.*s\n", (int)size, buffer);
6063     CloseHandle(file);
6064 }
6065 
test_deferred_action(void)6066 static void test_deferred_action(void)
6067 {
6068     char path[200], file[200], buffer[211];
6069     UINT r;
6070 
6071     GetTempPathA(sizeof(path), path);
6072     GetTempFileNameA(path, "da", 0, file);
6073     sprintf(buffer, "TESTPATH=\"%s\"", file);
6074 
6075     create_database(msifile, da_tables, ARRAY_SIZE(da_tables));
6076 
6077     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6078 
6079     r = MsiInstallProductA(msifile, buffer);
6080     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6081     {
6082         skip("Not enough rights to perform tests\n");
6083         goto error;
6084     }
6085     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6086 
6087     check_file_matches(file, "onetwo");
6088 
6089     ok(DeleteFileA(file), "Directory not created\n");
6090 
6091 error:
6092     DeleteFileA(msifile);
6093 }
6094 
test_wow64(void)6095 static void test_wow64(void)
6096 {
6097     void *cookie;
6098     UINT r;
6099 
6100     if (!is_wow64)
6101     {
6102         skip("test must be run on WoW64\n");
6103         return;
6104     }
6105 
6106     if (!is_process_elevated())
6107     {
6108         skip("process is limited\n");
6109         return;
6110     }
6111 
6112     create_test_files();
6113     create_database_template(msifile, x64_tables, ARRAY_SIZE(x64_tables), 200, "x64;0");
6114     r = MsiInstallProductA(msifile, NULL);
6115     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6116     {
6117         skip("Not enough rights to perform tests\n");
6118         goto error;
6119     }
6120 
6121     Wow64DisableWow64FsRedirection(&cookie);
6122 
6123     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
6124     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
6125     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
6126     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
6127     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
6128     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
6129     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
6130     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
6131     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
6132     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
6133     ok(!delete_pf("msitest", FALSE), "Directory created\n");
6134 
6135     ok(delete_pf_native("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6136     ok(delete_pf_native("msitest\\cabout\\new", FALSE), "Directory not created\n");
6137     ok(delete_pf_native("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6138     ok(delete_pf_native("msitest\\cabout", FALSE), "Directory not created\n");
6139     ok(delete_pf_native("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6140     ok(delete_pf_native("msitest\\changed", FALSE), "Directory not created\n");
6141     ok(delete_pf_native("msitest\\first\\two.txt", TRUE), "File not installed\n");
6142     ok(delete_pf_native("msitest\\first", FALSE), "Directory not created\n");
6143     ok(delete_pf_native("msitest\\one.txt", TRUE), "File not installed\n");
6144     ok(delete_pf_native("msitest\\filename", TRUE), "File not installed\n");
6145     ok(delete_pf_native("msitest", FALSE), "Directory not created\n");
6146 
6147     Wow64RevertWow64FsRedirection(cookie);
6148 
6149 error:
6150     delete_test_files();
6151     DeleteFileA(msifile);
6152 }
6153 
6154 /* Test what actions cause resolution of SourceDir when executed. */
test_source_resolution(void)6155 static void test_source_resolution(void)
6156 {
6157     UINT r;
6158 
6159     if (!is_process_elevated())
6160     {
6161         skip( "process is limited\n" );
6162         return;
6163     }
6164 
6165     create_test_files();
6166     create_database(msifile, sr_tables, ARRAY_SIZE(sr_tables));
6167 
6168     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6169 
6170     r = MsiInstallProductA(msifile, "RESOLVE_SOURCE=1");
6171     ok(r == ERROR_SUCCESS, "got %u\n", r);
6172 
6173     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
6174     ok(r == ERROR_SUCCESS, "got %u\n", r);
6175 
6176     r = MsiInstallProductA(msifile, "INSTALL_FILES=1");
6177     ok(r == ERROR_SUCCESS, "got %u\n", r);
6178 
6179     delete_pf_files();
6180     delete_test_files();
6181     DeleteFileA(msifile);
6182 }
6183 
START_TEST(install)6184 START_TEST(install)
6185 {
6186     DWORD len;
6187     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
6188 
6189     if (!is_process_elevated()) restart_as_admin_elevated();
6190 
6191     subtest("custom");
6192 
6193     IsWow64Process(GetCurrentProcess(), &is_wow64);
6194 
6195     GetCurrentDirectoryA(MAX_PATH, prev_path);
6196     GetTempPathA(MAX_PATH, temp_path);
6197     SetCurrentDirectoryA(temp_path);
6198 
6199     lstrcpyA(CURR_DIR, temp_path);
6200     len = lstrlenA(CURR_DIR);
6201 
6202     if(len && (CURR_DIR[len - 1] == '\\'))
6203         CURR_DIR[len - 1] = 0;
6204 
6205     ok(get_system_dirs(), "failed to retrieve system dirs\n");
6206     ok(get_user_dirs(), "failed to retrieve user dirs\n");
6207 
6208     /* Create only one log file and don't append. We have to pass something
6209      * for the log mode for this to work. The logfile needs to have an absolute
6210      * path otherwise we still end up with some extra logfiles as some tests
6211      * change the current directory.
6212      */
6213     lstrcpyA(log_file, temp_path);
6214     lstrcatA(log_file, "\\msitest.log");
6215     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
6216 
6217     test_MsiInstallProduct();
6218     test_MsiSetComponentState();
6219     test_packagecoltypes();
6220     test_continuouscabs();
6221     test_caborder();
6222     test_mixedmedia();
6223     test_samesequence();
6224     test_uiLevelFlags();
6225     test_readonlyfile();
6226     test_readonlyfile_cab();
6227     test_setdirproperty();
6228     test_cabisextracted();
6229     test_transformprop();
6230     test_currentworkingdir();
6231     test_admin();
6232     test_adminprops();
6233     test_missingcab();
6234     test_sourcefolder();
6235     test_customaction1();
6236     test_customaction51();
6237     test_installstate();
6238     test_sourcepath();
6239     test_missingcomponent();
6240     test_sourcedirprop();
6241     test_adminimage();
6242     test_propcase();
6243     test_int_widths();
6244     test_shortcut();
6245     test_preselected();
6246     test_installed_prop();
6247     test_file_in_use();
6248     test_file_in_use_cab();
6249     test_allusers_prop();
6250     test_feature_override();
6251     test_icon_table();
6252     test_package_validation();
6253     test_upgrade_code();
6254     test_mixed_package();
6255     test_volume_props();
6256     test_shared_component();
6257     test_remove_upgrade_code();
6258     test_feature_tree();
6259     test_deferred_action();
6260     test_wow64();
6261     test_source_resolution();
6262 
6263     DeleteFileA(customdll);
6264     DeleteFileA(log_file);
6265     SetCurrentDirectoryA(prev_path);
6266 }
6267