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