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