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