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