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