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