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