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