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