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