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