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