dinput: Fix printing NULL strings.
[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 #if 0  /* not implemented in wine yet */
3772     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
3773     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3774 #endif
3775
3776     MsiCloseHandle(hdb1);
3777     MsiCloseHandle(hdb2);
3778 }
3779
3780 /* data for generating a transform */
3781
3782 /* tables transform names - encoded as they would be in an msi database file */
3783 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3784 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3785 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3786
3787 /* data in each table */
3788 static const char data1[] = /* _StringData */
3789     "propval";  /* all the strings squashed together */
3790
3791 static const WCHAR data2[] = { /* _StringPool */
3792 /*  len, refs */
3793     0,   0,    /* string 0 ''     */
3794     4,   1,    /* string 1 'prop' */
3795     3,   1,    /* string 2 'val'  */
3796 };
3797
3798 static const WCHAR data3[] = { /* Property */
3799     0x0201, 0x0001, 0x0002,
3800 };
3801
3802 static const struct {
3803     LPCWSTR name;
3804     const void *data;
3805     DWORD size;
3806 } table_transform_data[] =
3807 {
3808     { name1, data1, sizeof data1 - 1 },
3809     { name2, data2, sizeof data2 },
3810     { name3, data3, sizeof data3 },
3811 };
3812
3813 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
3814
3815 static void generate_transform_manual(void)
3816 {
3817     IStorage *stg = NULL;
3818     IStream *stm;
3819     WCHAR name[0x20];
3820     HRESULT r;
3821     DWORD i, count;
3822     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
3823
3824     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
3825
3826     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
3827
3828     r = StgCreateDocfile(name, mode, 0, &stg);
3829     ok(r == S_OK, "failed to create storage\n");
3830     if (!stg)
3831         return;
3832
3833     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
3834     ok(r == S_OK, "failed to set storage type\n");
3835
3836     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
3837     {
3838         r = IStorage_CreateStream(stg, table_transform_data[i].name,
3839                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3840         if (FAILED(r))
3841         {
3842             ok(0, "failed to create stream %08x\n", r);
3843             continue;
3844         }
3845
3846         r = IStream_Write(stm, table_transform_data[i].data,
3847                           table_transform_data[i].size, &count);
3848         if (FAILED(r) || count != table_transform_data[i].size)
3849             ok(0, "failed to write stream\n");
3850         IStream_Release(stm);
3851     }
3852
3853     IStorage_Release(stg);
3854
3855     set_transform_summary_info();
3856 }
3857
3858 static void test_transformprop(void)
3859 {
3860     UINT r;
3861
3862     if (is_process_limited())
3863     {
3864         skip("process is limited\n");
3865         return;
3866     }
3867
3868     CreateDirectoryA("msitest", NULL);
3869     create_file("msitest\\augustus", 500);
3870
3871     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
3872
3873     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3874
3875     r = MsiInstallProductA(msifile, NULL);
3876     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3877     {
3878         skip("Not enough rights to perform tests\n");
3879         goto error;
3880     }
3881     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3882     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3883     ok(!delete_pf("msitest", FALSE), "Directory created\n");
3884
3885     if (0)
3886         generate_transform();
3887     else
3888         generate_transform_manual();
3889
3890     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
3891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3892     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3893     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3894
3895 error:
3896     /* Delete the files in the temp (current) folder */
3897     DeleteFile(msifile);
3898     DeleteFile(msifile2);
3899     DeleteFile(mstfile);
3900     DeleteFile("msitest\\augustus");
3901     RemoveDirectory("msitest");
3902 }
3903
3904 static void test_currentworkingdir(void)
3905 {
3906     UINT r;
3907     CHAR drive[MAX_PATH], path[MAX_PATH];
3908     LPSTR ptr;
3909
3910     if (is_process_limited())
3911     {
3912         skip("process is limited\n");
3913         return;
3914     }
3915
3916     CreateDirectoryA("msitest", NULL);
3917     create_file("msitest\\augustus", 500);
3918
3919     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
3920
3921     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3922
3923     CreateDirectoryA("diffdir", NULL);
3924     SetCurrentDirectoryA("diffdir");
3925
3926     sprintf(path, "..\\%s", msifile);
3927     r = MsiInstallProductA(path, NULL);
3928     todo_wine
3929     {
3930         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
3931         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3932         ok(!delete_pf("msitest", FALSE), "Directory created\n");
3933     }
3934
3935     sprintf(path, "%s\\%s", CURR_DIR, msifile);
3936     r = MsiInstallProductA(path, NULL);
3937     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3938     {
3939         skip("Not enough rights to perform tests\n");
3940         goto error;
3941     }
3942     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3943     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3944     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3945
3946     lstrcpyA(drive, CURR_DIR);
3947     drive[2] = '\\';
3948     drive[3] = '\0';
3949     SetCurrentDirectoryA(drive);
3950
3951     lstrcpy(path, CURR_DIR);
3952     if (path[lstrlenA(path) - 1] != '\\')
3953         lstrcatA(path, "\\");
3954     lstrcatA(path, msifile);
3955     ptr = strchr(path, ':');
3956     ptr +=2;
3957
3958     r = MsiInstallProductA(ptr, NULL);
3959     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3960     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3961     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3962
3963 error:
3964     SetCurrentDirectoryA(CURR_DIR);
3965     DeleteFile(msifile);
3966     DeleteFile("msitest\\augustus");
3967     RemoveDirectory("msitest");
3968     RemoveDirectory("diffdir");
3969 }
3970
3971 static void set_admin_summary_info(const CHAR *name)
3972 {
3973     MSIHANDLE db, summary;
3974     UINT r;
3975
3976     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
3977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3978
3979     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
3980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3981
3982     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
3983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3984
3985     /* write the summary changes back to the stream */
3986     r = MsiSummaryInfoPersist(summary);
3987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3988
3989     MsiCloseHandle(summary);
3990
3991     r = MsiDatabaseCommit(db);
3992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3993
3994     MsiCloseHandle(db);
3995 }
3996
3997 static void test_admin(void)
3998 {
3999     UINT r;
4000
4001     CreateDirectoryA("msitest", NULL);
4002     create_file("msitest\\augustus", 500);
4003
4004     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
4005     set_admin_summary_info(msifile);
4006
4007     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4008
4009     r = MsiInstallProductA(msifile, NULL);
4010     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4011     {
4012         skip("Not enough rights to perform tests\n");
4013         goto error;
4014     }
4015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4016     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4017     ok(!delete_pf("msitest", FALSE), "Directory created\n");
4018     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
4019     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
4020
4021     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
4022     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4023     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4024     ok(!delete_pf("msitest", FALSE), "Directory created\n");
4025     todo_wine
4026     {
4027         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
4028         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
4029     }
4030
4031 error:
4032     DeleteFile(msifile);
4033     DeleteFile("msitest\\augustus");
4034     RemoveDirectory("msitest");
4035 }
4036
4037 static void set_admin_property_stream(LPCSTR file)
4038 {
4039     IStorage *stg;
4040     IStream *stm;
4041     WCHAR fileW[MAX_PATH];
4042     HRESULT hr;
4043     DWORD count;
4044     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
4045
4046     /* AdminProperties */
4047     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
4048     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
4049         'M','y','P','r','o','p','=','4','2',0};
4050
4051     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
4052
4053     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
4054     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4055     if (!stg)
4056         return;
4057
4058     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4059     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4060
4061     hr = IStream_Write(stm, data, sizeof(data), &count);
4062     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4063
4064     IStream_Release(stm);
4065     IStorage_Release(stg);
4066 }
4067
4068 static void test_adminprops(void)
4069 {
4070     UINT r;
4071
4072     if (is_process_limited())
4073     {
4074         skip("process is limited\n");
4075         return;
4076     }
4077
4078     CreateDirectoryA("msitest", NULL);
4079     create_file("msitest\\augustus", 500);
4080
4081     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
4082     set_admin_summary_info(msifile);
4083     set_admin_property_stream(msifile);
4084
4085     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4086
4087     r = MsiInstallProductA(msifile, NULL);
4088     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4089     {
4090         skip("Not enough rights to perform tests\n");
4091         goto error;
4092     }
4093     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4094     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4095     ok(delete_pf("msitest", FALSE), "Directory created\n");
4096
4097 error:
4098     DeleteFile(msifile);
4099     DeleteFile("msitest\\augustus");
4100     RemoveDirectory("msitest");
4101 }
4102
4103 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4104 {
4105     CHAR path[MAX_PATH];
4106
4107     lstrcpyA(path, PROG_FILES_DIR);
4108     lstrcatA(path, "\\");
4109     lstrcatA(path, file);
4110
4111     if (is_file)
4112         create_file_data(path, data, 500);
4113     else
4114         CreateDirectoryA(path, NULL);
4115 }
4116
4117 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4118
4119 static void test_missingcab(void)
4120 {
4121     UINT r;
4122
4123     if (is_process_limited())
4124     {
4125         skip("process is limited\n");
4126         return;
4127     }
4128
4129     CreateDirectoryA("msitest", NULL);
4130     create_file("msitest\\augustus", 500);
4131     create_file("maximus", 500);
4132     create_file("tiberius", 500);
4133
4134     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
4135
4136     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4137
4138     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4139     create_cab_file("test4.cab", MEDIA_SIZE, "tiberius\0");
4140
4141     create_pf("msitest", FALSE);
4142     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4143     create_pf_data("msitest\\tiberius", "abcdefgh", TRUE);
4144
4145     r = MsiInstallProductA(msifile, NULL);
4146     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4147     {
4148         skip("Not enough rights to perform tests\n");
4149         goto error;
4150     }
4151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4152     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4153     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4154     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4155     ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n");
4156     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
4157     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
4158     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4159
4160     create_pf("msitest", FALSE);
4161     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4162     create_pf_data("msitest\\tiberius", "abcdefgh", TRUE);
4163     create_pf("msitest\\gaius", TRUE);
4164
4165     r = MsiInstallProductA(msifile, "GAIUS=1");
4166     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4167     todo_wine
4168     {
4169         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
4170         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4171     }
4172     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
4173     ok(compare_pf_data("msitest\\tiberius", "abcdefgh", sizeof("abcdefgh")), "Wrong file contents\n");
4174     ok(delete_pf("msitest\\tiberius", TRUE), "File removed\n");
4175     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
4176     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4177
4178 error:
4179     delete_pf("msitest", FALSE);
4180     DeleteFile("msitest\\augustus");
4181     RemoveDirectory("msitest");
4182     DeleteFile("maximus");
4183     DeleteFile("tiberius");
4184     DeleteFile("test1.cab");
4185     DeleteFile("test4.cab");
4186     DeleteFile(msifile);
4187 }
4188
4189 static void test_sourcefolder(void)
4190 {
4191     UINT r;
4192
4193     if (is_process_limited())
4194     {
4195         skip("process is limited\n");
4196         return;
4197     }
4198
4199     CreateDirectoryA("msitest", NULL);
4200     create_file("augustus", 500);
4201
4202     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
4203
4204     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4205
4206     r = MsiInstallProductA(msifile, NULL);
4207     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4208     {
4209         skip("Not enough rights to perform tests\n");
4210         goto error;
4211     }
4212     ok(r == ERROR_INSTALL_FAILURE,
4213        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4214     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4215     todo_wine
4216     {
4217         ok(!delete_pf("msitest", FALSE), "Directory created\n");
4218     }
4219     RemoveDirectoryA("msitest");
4220
4221     r = MsiInstallProductA(msifile, NULL);
4222     ok(r == ERROR_INSTALL_FAILURE,
4223        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4224     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4225     todo_wine
4226     {
4227         ok(!delete_pf("msitest", FALSE), "Directory created\n");
4228     }
4229
4230 error:
4231     DeleteFile(msifile);
4232     DeleteFile("augustus");
4233 }
4234
4235 static void test_customaction51(void)
4236 {
4237     UINT r;
4238
4239     if (is_process_limited())
4240     {
4241         skip("process is limited\n");
4242         return;
4243     }
4244
4245     CreateDirectoryA("msitest", NULL);
4246     create_file("msitest\\augustus", 500);
4247
4248     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
4249
4250     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4251
4252     r = MsiInstallProductA(msifile, NULL);
4253     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4254     {
4255         skip("Not enough rights to perform tests\n");
4256         goto error;
4257     }
4258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4259     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4260     ok(delete_pf("msitest", FALSE), "Directory created\n");
4261
4262 error:
4263     DeleteFile(msifile);
4264     DeleteFile("msitest\\augustus");
4265     RemoveDirectory("msitest");
4266 }
4267
4268 static void test_installstate(void)
4269 {
4270     UINT r;
4271
4272     if (is_process_limited())
4273     {
4274         skip("process is limited\n");
4275         return;
4276     }
4277
4278     CreateDirectoryA("msitest", NULL);
4279     create_file("msitest\\alpha", 500);
4280     create_file("msitest\\beta", 500);
4281     create_file("msitest\\gamma", 500);
4282     create_file("msitest\\theta", 500);
4283     create_file("msitest\\delta", 500);
4284     create_file("msitest\\epsilon", 500);
4285     create_file("msitest\\zeta", 500);
4286     create_file("msitest\\iota", 500);
4287     create_file("msitest\\eta", 500);
4288     create_file("msitest\\kappa", 500);
4289     create_file("msitest\\lambda", 500);
4290     create_file("msitest\\mu", 500);
4291
4292     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
4293
4294     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4295
4296     r = MsiInstallProductA(msifile, NULL);
4297     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4298     {
4299         skip("Not enough rights to perform tests\n");
4300         goto error;
4301     }
4302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4303     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4304     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4305     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4306     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4307     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4308     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4309     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4310     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4311     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4312     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4313     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4314     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4315     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4316
4317     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
4318     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4319     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4320     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4321     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4322     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4323     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4324     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
4325     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4326     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4327     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
4328     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4329     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4330     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4331     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4332
4333     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
4334     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4335     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4336     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4337     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4338     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4339     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4340     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4341     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4342     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4343     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4344     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4345     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4346     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4347     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4348
4349     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
4350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4351     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
4352     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4353     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4354     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
4355     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4356     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4357     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4358     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4359     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4360     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4361     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4362     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4363     ok(!delete_pf("msitest", FALSE), "Directory created\n");
4364
4365 error:
4366     DeleteFile(msifile);
4367     DeleteFile("msitest\\alpha");
4368     DeleteFile("msitest\\beta");
4369     DeleteFile("msitest\\gamma");
4370     DeleteFile("msitest\\theta");
4371     DeleteFile("msitest\\delta");
4372     DeleteFile("msitest\\epsilon");
4373     DeleteFile("msitest\\zeta");
4374     DeleteFile("msitest\\iota");
4375     DeleteFile("msitest\\eta");
4376     DeleteFile("msitest\\kappa");
4377     DeleteFile("msitest\\lambda");
4378     DeleteFile("msitest\\mu");
4379     RemoveDirectory("msitest");
4380 }
4381
4382 static const struct sourcepathmap
4383 {
4384     BOOL sost; /* shortone\shorttwo */
4385     BOOL solt; /* shortone\longtwo */
4386     BOOL lost; /* longone\shorttwo */
4387     BOOL lolt; /* longone\longtwo */
4388     BOOL soste; /* shortone\shorttwo source exists */
4389     BOOL solte; /* shortone\longtwo source exists */
4390     BOOL loste; /* longone\shorttwo source exists */
4391     BOOL lolte; /* longone\longtwo source exists */
4392     UINT err;
4393     DWORD size;
4394 } spmap[256] =
4395 {
4396     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4397     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4398     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4399     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4400     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4401     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4402     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4403     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4404     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4405     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4406     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4407     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4408     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4409     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4410     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4411     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4412     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4413     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4414     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4415     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4416     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4417     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4418     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4419     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4420     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4421     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4422     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4423     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4424     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4425     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4426     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4427     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4428     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4429     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4430     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4431     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4432     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4433     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4434     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4435     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4436     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4437     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4438     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4439     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4440     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4441     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4442     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4443     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4444     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4445     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4446     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4447     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4448     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4449     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4450     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4451     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4452     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4453     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4454     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4455     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4456     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4457     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4458     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4459     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4460     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4461     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4462     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4463     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4464     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4465     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4466     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4467     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4468     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4469     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4470     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4471     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4472     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4473     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4474     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4475     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4476     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4477     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4478     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4479     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4480     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4481     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4482     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4483     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4484     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4485     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4486     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4487     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4488     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4489     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4490     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4491     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4492     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4493     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4494     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4495     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4496     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4497     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4498     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4499     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4500     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4501     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4502     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4503     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4504     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4505     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4506     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4507     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4508     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4509     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4510     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4511     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4512     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4513     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4514     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4515     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4516     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4517     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4518     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4519     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4520     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4521     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4522     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4523     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4524     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4525     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4526     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4527     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4528     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4529     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4530     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4531     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4532     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4533     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4534     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4535     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4536     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4537     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4538     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4539     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4540     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4541     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4542     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4543     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4544     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4545     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4546     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4547     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4548     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4549     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4550     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4551     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4552     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4553     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4554     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4555     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4556     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4557     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4558     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4559     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4560     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4561     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4562     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4563     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4564     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4565     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4566     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4567     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4568     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4569     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4570     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4571     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4572     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4573     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4574     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4575     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4576     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4577     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4578     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4579     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4580     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4581     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4582     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4583     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4584     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4585     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4586     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4587     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4588     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4589     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4590     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4591     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4592     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4593     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4594     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4595     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4596     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4597     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4598     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4599     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4600     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4601     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4602     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4603     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4604     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4605     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4606     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4607     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4608     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4609     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4610     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4611     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4612     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4613     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4614     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4615     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4616     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4617     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4618     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4619     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4620     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4621     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4622     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4623     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4624     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4625     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4626     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4627     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4628     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4629     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4630     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4631     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4632     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4633     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4634     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4635     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4636     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4637     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4638     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4639     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4640     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4641     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4642     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4643     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4644     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4645     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4646     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4647     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4648     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4649     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4650     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4651     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4652 };
4653
4654 static DWORD get_pf_file_size(LPCSTR file)
4655 {
4656     CHAR path[MAX_PATH];
4657     HANDLE hfile;
4658     DWORD size;
4659
4660     lstrcpyA(path, PROG_FILES_DIR);
4661     lstrcatA(path, "\\");
4662     lstrcatA(path, file);
4663
4664     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
4665     if (hfile == INVALID_HANDLE_VALUE)
4666         return INVALID_FILE_SIZE;
4667
4668     size = GetFileSize(hfile, NULL);
4669     CloseHandle(hfile);
4670     return size;
4671 }
4672
4673 static void test_sourcepath(void)
4674 {
4675     UINT r, i;
4676
4677     if (!winetest_interactive)
4678     {
4679         skip("Run in interactive mode to run source path tests.\n");
4680         return;
4681     }
4682
4683     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
4684
4685     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4686
4687     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
4688     {
4689         if (spmap[i].sost)
4690         {
4691             CreateDirectoryA("shortone", NULL);
4692             CreateDirectoryA("shortone\\shorttwo", NULL);
4693         }
4694
4695         if (spmap[i].solt)
4696         {
4697             CreateDirectoryA("shortone", NULL);
4698             CreateDirectoryA("shortone\\longtwo", NULL);
4699         }
4700
4701         if (spmap[i].lost)
4702         {
4703             CreateDirectoryA("longone", NULL);
4704             CreateDirectoryA("longone\\shorttwo", NULL);
4705         }
4706
4707         if (spmap[i].lolt)
4708         {
4709             CreateDirectoryA("longone", NULL);
4710             CreateDirectoryA("longone\\longtwo", NULL);
4711         }
4712
4713         if (spmap[i].soste)
4714             create_file("shortone\\shorttwo\\augustus", 50);
4715         if (spmap[i].solte)
4716             create_file("shortone\\longtwo\\augustus", 100);
4717         if (spmap[i].loste)
4718             create_file("longone\\shorttwo\\augustus", 150);
4719         if (spmap[i].lolte)
4720             create_file("longone\\longtwo\\augustus", 200);
4721
4722         r = MsiInstallProductA(msifile, NULL);
4723         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
4724         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
4725            "%d: Expected %d, got %d\n", i, spmap[i].size,
4726            get_pf_file_size("msitest\\augustus"));
4727
4728         if (r == ERROR_SUCCESS)
4729         {
4730             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
4731             ok(delete_pf("msitest", FALSE), "%d: Directory not created\n", i);
4732         }
4733         else
4734         {
4735             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
4736             todo_wine ok(!delete_pf("msitest", FALSE), "%d: Directory installed\n", i);
4737         }
4738
4739         DeleteFileA("shortone\\shorttwo\\augustus");
4740         DeleteFileA("shortone\\longtwo\\augustus");
4741         DeleteFileA("longone\\shorttwo\\augustus");
4742         DeleteFileA("longone\\longtwo\\augustus");
4743         RemoveDirectoryA("shortone\\shorttwo");
4744         RemoveDirectoryA("shortone\\longtwo");
4745         RemoveDirectoryA("longone\\shorttwo");
4746         RemoveDirectoryA("longone\\longtwo");
4747         RemoveDirectoryA("shortone");
4748         RemoveDirectoryA("longone");
4749     }
4750
4751     DeleteFileA(msifile);
4752 }
4753
4754 static void test_MsiConfigureProductEx(void)
4755 {
4756     UINT r;
4757     LONG res;
4758     DWORD type, size;
4759     HKEY props, source;
4760     CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
4761     REGSAM access = KEY_ALL_ACCESS;
4762
4763     if (is_process_limited())
4764     {
4765         skip("process is limited\n");
4766         return;
4767     }
4768
4769     CreateDirectoryA("msitest", NULL);
4770     create_file("msitest\\hydrogen", 500);
4771     create_file("msitest\\helium", 500);
4772     create_file("msitest\\lithium", 500);
4773
4774     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
4775
4776     if (is_wow64)
4777         access |= KEY_WOW64_64KEY;
4778
4779     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4780
4781     /* NULL szProduct */
4782     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
4783                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
4784     ok(r == ERROR_INVALID_PARAMETER,
4785        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4786
4787     /* empty szProduct */
4788     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
4789                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
4790     ok(r == ERROR_INVALID_PARAMETER,
4791        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4792
4793     /* garbage szProduct */
4794     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
4795                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
4796     ok(r == ERROR_INVALID_PARAMETER,
4797        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4798
4799     /* guid without brackets */
4800     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
4801                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
4802                                "PROPVAR=42");
4803     ok(r == ERROR_INVALID_PARAMETER,
4804        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4805
4806     /* guid with brackets */
4807     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
4808                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
4809                                "PROPVAR=42");
4810     ok(r == ERROR_UNKNOWN_PRODUCT,
4811        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4812
4813     /* same length as guid, but random */
4814     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
4815                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
4816                                "PROPVAR=42");
4817     ok(r == ERROR_UNKNOWN_PRODUCT,
4818        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4819
4820     /* product not installed yet */
4821     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4822                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
4823                                "PROPVAR=42");
4824     ok(r == ERROR_UNKNOWN_PRODUCT,
4825        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4826
4827     /* install the product, per-user unmanaged */
4828     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
4829     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4830     {
4831         skip("Not enough rights to perform tests\n");
4832         goto error;
4833     }
4834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4835     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4836     ok(pf_exists("msitest\\helium"), "File not installed\n");
4837     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4838     ok(pf_exists("msitest"), "File not installed\n");
4839
4840     /* product is installed per-user managed, remove it */
4841     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4842                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
4843                                "PROPVAR=42");
4844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4845     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
4846     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
4847     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
4848     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
4849
4850     /* product has been removed */
4851     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4852                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
4853                                "PROPVAR=42");
4854     ok(r == ERROR_UNKNOWN_PRODUCT,
4855        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4856
4857     /* install the product, machine */
4858     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
4859     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4860     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4861     ok(pf_exists("msitest\\helium"), "File not installed\n");
4862     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4863     ok(pf_exists("msitest"), "File not installed\n");
4864
4865     /* product is installed machine, remove it */
4866     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4867                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
4868                                "PROPVAR=42");
4869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4870     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
4871     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
4872     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
4873     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
4874
4875     /* product has been removed */
4876     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4877                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
4878                                "PROPVAR=42");
4879     ok(r == ERROR_UNKNOWN_PRODUCT,
4880        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4881
4882     /* install the product, machine */
4883     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
4884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4885     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4886     ok(pf_exists("msitest\\helium"), "File not installed\n");
4887     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4888     ok(pf_exists("msitest"), "File not installed\n");
4889
4890     DeleteFileA(msifile);
4891
4892     /* msifile is removed */
4893     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4894                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
4895                                "PROPVAR=42");
4896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4897     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
4898     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
4899     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
4900     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
4901
4902     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
4903
4904     /* install the product, machine */
4905     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
4906     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4907     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4908     ok(pf_exists("msitest\\helium"), "File not installed\n");
4909     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4910     ok(pf_exists("msitest"), "File not installed\n");
4911
4912     DeleteFileA(msifile);
4913
4914     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
4915     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
4916     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
4917
4918     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
4919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4920
4921     type = REG_SZ;
4922     size = MAX_PATH;
4923     res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
4924                            (LPBYTE)localpackage, &size);
4925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4926
4927     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
4928                          (const BYTE *)"C:\\idontexist.msi", 18);
4929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4930
4931     /* LocalPackage is used to find the cached msi package */
4932     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4933                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
4934                                "PROPVAR=42");
4935     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
4936        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
4937     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4938     ok(pf_exists("msitest\\helium"), "File not installed\n");
4939     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4940     ok(pf_exists("msitest"), "File not installed\n");
4941
4942     RegCloseKey(props);
4943     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
4944
4945     /* LastUsedSource can be used as a last resort */
4946     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4947                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
4948                                "PROPVAR=42");
4949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4950     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
4951     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
4952     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
4953     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
4954     DeleteFileA( localpackage );
4955
4956     /* install the product, machine */
4957     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
4958     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4959     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4960     ok(pf_exists("msitest\\helium"), "File not installed\n");
4961     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4962     ok(pf_exists("msitest"), "File not installed\n");
4963
4964     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
4965     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
4966     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
4967
4968     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
4969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4970
4971     type = REG_SZ;
4972     size = MAX_PATH;
4973     res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
4974                            (LPBYTE)localpackage, &size);
4975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4976
4977     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
4978                          (const BYTE *)"C:\\idontexist.msi", 18);
4979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4980
4981     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
4982     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
4983
4984     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
4985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4986
4987     type = REG_SZ;
4988     size = MAX_PATH;
4989     res = RegQueryValueExA(source, "PackageName", NULL, &type,
4990                            (LPBYTE)packagename, &size);
4991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4992
4993     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
4994                          (const BYTE *)"idontexist.msi", 15);
4995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4996
4997     /* SourceList is altered */
4998     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
4999                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5000                                "PROPVAR=42");
5001     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
5002        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
5003     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5004     ok(pf_exists("msitest\\helium"), "File not installed\n");
5005     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5006     ok(pf_exists("msitest"), "File not installed\n");
5007
5008     /* restore PackageName */
5009     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
5010                          (const BYTE *)packagename, lstrlenA(packagename) + 1);
5011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5012
5013     /* restore LocalPackage */
5014     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
5015                          (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
5016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5017
5018     /* finally remove the product */
5019     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5020                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5021                                "PROPVAR=42");
5022     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5023     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5024     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5025     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5026     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
5027
5028     RegCloseKey(source);
5029     RegCloseKey(props);
5030
5031 error:
5032     DeleteFileA("msitest\\hydrogen");
5033     DeleteFileA("msitest\\helium");
5034     DeleteFileA("msitest\\lithium");
5035     RemoveDirectoryA("msitest");
5036     DeleteFileA(msifile);
5037 }
5038
5039 static void test_missingcomponent(void)
5040 {
5041     UINT r;
5042
5043     if (is_process_limited())
5044     {
5045         skip("process is limited\n");
5046         return;
5047     }
5048
5049     CreateDirectoryA("msitest", NULL);
5050     create_file("msitest\\hydrogen", 500);
5051     create_file("msitest\\helium", 500);
5052     create_file("msitest\\lithium", 500);
5053     create_file("beryllium", 500);
5054
5055     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
5056
5057     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5058
5059     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
5060     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5061     {
5062         skip("Not enough rights to perform tests\n");
5063         goto error;
5064     }
5065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5066     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5067     ok(pf_exists("msitest\\helium"), "File not installed\n");
5068     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5069     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5070     ok(pf_exists("msitest"), "File not installed\n");
5071
5072     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
5073     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5074     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5075     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5076     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5077     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5078     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
5079
5080 error:
5081     DeleteFileA(msifile);
5082     DeleteFileA("msitest\\hydrogen");
5083     DeleteFileA("msitest\\helium");
5084     DeleteFileA("msitest\\lithium");
5085     DeleteFileA("beryllium");
5086     RemoveDirectoryA("msitest");
5087 }
5088
5089 static void test_sourcedirprop(void)
5090 {
5091     UINT r;
5092     CHAR props[MAX_PATH];
5093
5094     if (is_process_limited())
5095     {
5096         skip("process is limited\n");
5097         return;
5098     }
5099
5100     CreateDirectoryA("msitest", NULL);
5101     create_file("msitest\\augustus", 500);
5102
5103     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
5104
5105     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5106
5107     r = MsiInstallProductA(msifile, NULL);
5108     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5109     {
5110         skip("Not enough rights to perform tests\n");
5111         goto error;
5112     }
5113     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5114     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5115     ok(delete_pf("msitest", FALSE), "Directory created\n");
5116
5117     DeleteFile("msitest\\augustus");
5118     RemoveDirectory("msitest");
5119
5120     CreateDirectoryA("altsource", NULL);
5121     CreateDirectoryA("altsource\\msitest", NULL);
5122     create_file("altsource\\msitest\\augustus", 500);
5123
5124     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
5125
5126     r = MsiInstallProductA(msifile, props);
5127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5128     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5129     ok(delete_pf("msitest", FALSE), "Directory created\n");
5130
5131     DeleteFile("altsource\\msitest\\augustus");
5132     RemoveDirectory("altsource\\msitest");
5133     RemoveDirectory("altsource");
5134
5135 error:
5136     DeleteFile("msitest\\augustus");
5137     RemoveDirectory("msitest");
5138     DeleteFile(msifile);
5139 }
5140
5141 static void test_adminimage(void)
5142 {
5143     UINT r;
5144
5145     if (is_process_limited())
5146     {
5147         skip("process is limited\n");
5148         return;
5149     }
5150
5151     CreateDirectoryA("msitest", NULL);
5152     CreateDirectoryA("msitest\\first", NULL);
5153     CreateDirectoryA("msitest\\second", NULL);
5154     CreateDirectoryA("msitest\\cabout", NULL);
5155     CreateDirectoryA("msitest\\cabout\\new", NULL);
5156     create_file("msitest\\one.txt", 100);
5157     create_file("msitest\\first\\two.txt", 100);
5158     create_file("msitest\\second\\three.txt", 100);
5159     create_file("msitest\\cabout\\four.txt", 100);
5160     create_file("msitest\\cabout\\new\\five.txt", 100);
5161     create_file("msitest\\filename", 100);
5162     create_file("msitest\\service.exe", 100);
5163
5164     create_database_wordcount(msifile, ai_tables,
5165                               sizeof(ai_tables) / sizeof(msi_table),
5166                               100, msidbSumInfoSourceTypeAdminImage, ";1033");
5167
5168     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5169
5170     r = MsiInstallProductA(msifile, NULL);
5171     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5172     {
5173         skip("Not enough rights to perform tests\n");
5174         goto error;
5175     }
5176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5177
5178     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5179     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5180     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5181     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5182     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5183     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5184     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5185     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5186     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5187     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5188     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5189     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5190
5191 error:
5192     DeleteFileA("msifile");
5193     DeleteFileA("msitest\\cabout\\new\\five.txt");
5194     DeleteFileA("msitest\\cabout\\four.txt");
5195     DeleteFileA("msitest\\second\\three.txt");
5196     DeleteFileA("msitest\\first\\two.txt");
5197     DeleteFileA("msitest\\one.txt");
5198     DeleteFileA("msitest\\service.exe");
5199     DeleteFileA("msitest\\filename");
5200     RemoveDirectoryA("msitest\\cabout\\new");
5201     RemoveDirectoryA("msitest\\cabout");
5202     RemoveDirectoryA("msitest\\second");
5203     RemoveDirectoryA("msitest\\first");
5204     RemoveDirectoryA("msitest");
5205 }
5206
5207 static void test_propcase(void)
5208 {
5209     UINT r;
5210
5211     if (is_process_limited())
5212     {
5213         skip("process is limited\n");
5214         return;
5215     }
5216
5217     CreateDirectoryA("msitest", NULL);
5218     create_file("msitest\\augustus", 500);
5219
5220     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
5221
5222     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5223
5224     r = MsiInstallProductA(msifile, "MyProp=42");
5225     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5226     {
5227         skip("Not enough rights to perform tests\n");
5228         goto error;
5229     }
5230     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5231     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5232     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5233
5234 error:
5235     DeleteFile(msifile);
5236     DeleteFile("msitest\\augustus");
5237     RemoveDirectory("msitest");
5238 }
5239
5240 static void test_int_widths( void )
5241 {
5242     static const char int0[] = "int0\ni0\nint0\tint0\n1";
5243     static const char int1[] = "int1\ni1\nint1\tint1\n1";
5244     static const char int2[] = "int2\ni2\nint2\tint2\n1";
5245     static const char int3[] = "int3\ni3\nint3\tint3\n1";
5246     static const char int4[] = "int4\ni4\nint4\tint4\n1";
5247     static const char int5[] = "int5\ni5\nint5\tint5\n1";
5248     static const char int8[] = "int8\ni8\nint8\tint8\n1";
5249
5250     static const struct
5251     {
5252         const char  *data;
5253         unsigned int size;
5254         UINT         ret;
5255     }
5256     tests[] =
5257     {
5258         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
5259         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
5260         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
5261         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
5262         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
5263         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
5264         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
5265     };
5266
5267     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
5268     MSIHANDLE db;
5269     UINT r, i;
5270
5271     GetTempPathA(MAX_PATH, tmpdir);
5272     CreateDirectoryA(tmpdir, NULL);
5273
5274     strcpy(msitable, tmpdir);
5275     strcat(msitable, "\\msitable.idt");
5276
5277     strcpy(msidb, tmpdir);
5278     strcat(msidb, "\\msitest.msi");
5279
5280     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
5281     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5282
5283     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
5284     {
5285         write_file(msitable, tests[i].data, tests[i].size);
5286
5287         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
5288         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
5289
5290         r = MsiDatabaseCommit(db);
5291         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5292         DeleteFileA(msitable);
5293     }
5294
5295     MsiCloseHandle(db);
5296     DeleteFileA(msidb);
5297     RemoveDirectoryA(tmpdir);
5298 }
5299
5300 static void test_shortcut(void)
5301 {
5302     UINT r;
5303     HRESULT hr;
5304
5305     if (is_process_limited())
5306     {
5307         skip("process is limited\n");
5308         return;
5309     }
5310
5311     create_test_files();
5312     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
5313
5314     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5315
5316     r = MsiInstallProductA(msifile, NULL);
5317     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5318     {
5319         skip("Not enough rights to perform tests\n");
5320         goto error;
5321     }
5322     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5323
5324     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
5325     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
5326
5327     r = MsiInstallProductA(msifile, NULL);
5328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5329
5330     CoUninitialize();
5331
5332     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
5333     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
5334
5335     r = MsiInstallProductA(msifile, NULL);
5336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5337
5338     CoUninitialize();
5339
5340     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
5341     delete_pf("msitest\\cabout\\new", FALSE);
5342     delete_pf("msitest\\cabout\\four.txt", TRUE);
5343     delete_pf("msitest\\cabout", FALSE);
5344     delete_pf("msitest\\changed\\three.txt", TRUE);
5345     delete_pf("msitest\\changed", FALSE);
5346     delete_pf("msitest\\first\\two.txt", TRUE);
5347     delete_pf("msitest\\first", FALSE);
5348     delete_pf("msitest\\filename", TRUE);
5349     delete_pf("msitest\\one.txt", TRUE);
5350     delete_pf("msitest\\service.exe", TRUE);
5351     delete_pf("msitest\\Shortcut.lnk", TRUE);
5352     delete_pf("msitest", FALSE);
5353
5354 error:
5355     delete_test_files();
5356     DeleteFile(msifile);
5357 }
5358
5359 static void test_preselected(void)
5360 {
5361     UINT r;
5362
5363     if (is_process_limited())
5364     {
5365         skip("process is limited\n");
5366         return;
5367     }
5368
5369     create_test_files();
5370     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
5371
5372     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5373
5374     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
5375     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5376     {
5377         skip("Not enough rights to perform tests\n");
5378         goto error;
5379     }
5380     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5381
5382     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
5383     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
5384     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
5385     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
5386     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
5387     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
5388     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
5389     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
5390     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
5391     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5392     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
5393     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5394
5395     r = MsiInstallProductA(msifile, NULL);
5396     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5397
5398     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5399     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5400     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5401     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5402     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5403     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5404     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5405     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5406     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5407     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
5408     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5409     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5410
5411 error:
5412     delete_test_files();
5413     DeleteFile(msifile);
5414 }
5415
5416 static void test_installed_prop(void)
5417 {
5418     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
5419     UINT r;
5420
5421     if (is_process_limited())
5422     {
5423         skip("process is limited\n");
5424         return;
5425     }
5426
5427     create_test_files();
5428     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
5429
5430     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5431
5432     r = MsiInstallProductA(msifile, "FULL=1");
5433     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5434     {
5435         skip("Not enough rights to perform tests\n");
5436         goto error;
5437     }
5438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5439
5440     r = MsiInstallProductA(msifile, "FULL=1");
5441     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5442
5443     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
5444     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5445
5446     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5447     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5448     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5449     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5450     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5451     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5452     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5453     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5454     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5455     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
5456     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5457     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5458
5459     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5461
5462 error:
5463     delete_test_files();
5464     DeleteFile(msifile);
5465 }
5466
5467 static void test_allusers_prop(void)
5468 {
5469     UINT r;
5470
5471     if (is_process_limited())
5472     {
5473         skip("process is limited\n");
5474         return;
5475     }
5476
5477     create_test_files();
5478     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
5479
5480     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5481
5482     /* ALLUSERS property unset */
5483     r = MsiInstallProductA(msifile, "FULL=1");
5484     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5485     {
5486         skip("Not enough rights to perform tests\n");
5487         goto error;
5488     }
5489     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5490
5491     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5492     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5493     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5494     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5495     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5496     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5497     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5498     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5499     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5500     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
5501     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5502     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5503
5504     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5506
5507     delete_test_files();
5508
5509     create_test_files();
5510     create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
5511
5512     /* ALLUSERS property set to 1 */
5513     r = MsiInstallProductA(msifile, "FULL=1");
5514     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5515
5516     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5517     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5518     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5519     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5520     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5521     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5522     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5523     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5524     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5525     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
5526     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5527     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5528
5529     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5531
5532     delete_test_files();
5533
5534     create_test_files();
5535     create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
5536
5537     /* ALLUSERS property set to 2 */
5538     r = MsiInstallProductA(msifile, "FULL=1");
5539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5540
5541     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5542     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5543     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5544     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5545     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5546     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5547     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5548     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5549     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5550     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
5551     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5552     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5553
5554     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5556
5557     delete_test_files();
5558
5559     create_test_files();
5560     create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
5561
5562     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
5563     r = MsiInstallProductA(msifile, "FULL=1");
5564     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5565
5566 error:
5567     delete_test_files();
5568     DeleteFile(msifile);
5569 }
5570
5571 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
5572 static char rename_ops[]      = "PendingFileRenameOperations";
5573
5574 static void process_pending_renames(HKEY hkey)
5575 {
5576     char *buf, *src, *dst, *buf2, *buf2ptr;
5577     DWORD size;
5578     LONG ret;
5579     BOOL found = FALSE;
5580
5581     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
5582     ok(!ret, "RegQueryValueExA failed %d\n", ret);
5583
5584     buf = HeapAlloc(GetProcessHeap(), 0, size + 1);
5585     buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1);
5586
5587     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
5588     buf[size] = 0;
5589     ok(!ret, "RegQueryValueExA failed %d\n", ret);
5590     if (ret) return;
5591
5592     for (src = buf; *src; src = dst + strlen(dst) + 1)
5593     {
5594         DWORD flags = MOVEFILE_COPY_ALLOWED;
5595         BOOL fileret;
5596
5597         dst = src + strlen(src) + 1;
5598
5599         if (!strstr(src, "msitest"))
5600         {
5601             lstrcpyA(buf2ptr, src);
5602             buf2ptr += strlen(src) + 1;
5603             if (*dst)
5604             {
5605                 lstrcpyA(buf2ptr, dst);
5606                 buf2ptr += strlen(dst) + 1;
5607             }
5608             buf2ptr++;
5609             continue;
5610         }
5611
5612         found = TRUE;
5613
5614         if (*dst == '!')
5615         {
5616             flags |= MOVEFILE_REPLACE_EXISTING;
5617             dst++;
5618         }
5619         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
5620         if (*dst)
5621         {
5622             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
5623             fileret = MoveFileExA(src, dst, flags);
5624             ok(fileret, "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
5625         }
5626         else
5627         {
5628             fileret = DeleteFileA(src);
5629             ok(fileret, "Failed to delete file %s (%u)\n", src, GetLastError());
5630         }
5631     }
5632
5633     ok(found, "Expected a 'msitest' entry\n");
5634
5635     if (*buf2)
5636         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2ptr + 1 - buf2);
5637     else
5638         RegDeleteValueA(hkey, rename_ops);
5639
5640     HeapFree(GetProcessHeap(), 0, buf);
5641     HeapFree(GetProcessHeap(), 0, buf2);
5642 }
5643
5644 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
5645 {
5646     DWORD len, data_len = strlen(data);
5647     HANDLE handle;
5648     char buf[128];
5649
5650     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
5651     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
5652
5653     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
5654     {
5655         CloseHandle(handle);
5656         return !memcmp(buf, data, data_len);
5657     }
5658     CloseHandle(handle);
5659     return FALSE;
5660 }
5661
5662 static void test_file_in_use(void)
5663 {
5664     UINT r;
5665     HANDLE file;
5666     HKEY hkey;
5667     char path[MAX_PATH];
5668
5669     if (is_process_limited())
5670     {
5671         skip("process is limited\n");
5672         return;
5673     }
5674
5675     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
5676
5677     CreateDirectoryA("msitest", NULL);
5678     create_file("msitest\\maximus", 500);
5679     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
5680
5681     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5682
5683     lstrcpy(path, PROG_FILES_DIR);
5684     lstrcat(path, "\\msitest");
5685     CreateDirectoryA(path, NULL);
5686
5687     lstrcat(path, "\\maximus");
5688     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
5689
5690     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
5691     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5692     {
5693         skip("Not enough rights to perform tests\n");
5694         goto error;
5695     }
5696     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
5697     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
5698     CloseHandle(file);
5699     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
5700
5701     process_pending_renames(hkey);
5702     RegCloseKey(hkey);
5703
5704     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
5705     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
5706     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
5707
5708     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5709     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5710
5711 error:
5712     RegCloseKey(hkey);
5713
5714     delete_pf("msitest\\maximus", TRUE);
5715     delete_pf("msitest", FALSE);
5716     DeleteFileA("msitest\\maximus");
5717     delete_test_files();
5718     DeleteFile(msifile);
5719 }
5720
5721 static void test_file_in_use_cab(void)
5722 {
5723     UINT r;
5724     HANDLE file;
5725     HKEY hkey;
5726     char path[MAX_PATH];
5727
5728     if (is_process_limited())
5729     {
5730         skip("process is limited\n");
5731         return;
5732     }
5733
5734     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
5735
5736     CreateDirectoryA("msitest", NULL);
5737     create_file("maximus", 500);
5738     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
5739     DeleteFile("maximus");
5740
5741     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
5742
5743     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5744
5745     lstrcpy(path, PROG_FILES_DIR);
5746     lstrcat(path, "\\msitest");
5747     CreateDirectoryA(path, NULL);
5748
5749     lstrcat(path, "\\maximus");
5750     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
5751
5752     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
5753     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5754     {
5755         skip("Not enough rights to perform tests\n");
5756         goto error;
5757     }
5758     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
5759     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
5760     CloseHandle(file);
5761     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
5762
5763     process_pending_renames(hkey);
5764     RegCloseKey(hkey);
5765
5766     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
5767     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
5768     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
5769
5770     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5772
5773 error:
5774     RegCloseKey(hkey);
5775
5776     delete_pf("msitest\\maximus", TRUE);
5777     delete_pf("msitest", FALSE);
5778     DeleteFileA("msitest\\maximus");
5779     delete_cab_files();
5780     delete_test_files();
5781     DeleteFile(msifile);
5782 }
5783
5784 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
5785 {
5786     return IDOK;
5787 }
5788
5789 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
5790 {
5791     return IDOK;
5792 }
5793
5794 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
5795 {
5796     return IDOK;
5797 }
5798
5799 static void test_MsiSetExternalUI(void)
5800 {
5801     INSTALLUI_HANDLERA ret_a;
5802     INSTALLUI_HANDLERW ret_w;
5803     INSTALLUI_HANDLER_RECORD prev;
5804     UINT error;
5805
5806     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
5807     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
5808
5809     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
5810     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
5811
5812     /* Not present before Installer 3.1 */
5813     if (!pMsiSetExternalUIRecord) {
5814         win_skip("MsiSetExternalUIRecord is not available\n");
5815         return;
5816     }
5817
5818     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
5819     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
5820     ok(prev == NULL, "expected NULL, got %p\n", prev);
5821
5822     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
5823     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
5824     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
5825     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
5826
5827     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
5828     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
5829
5830     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
5831     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
5832
5833     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
5834     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
5835
5836     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
5837     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
5838
5839     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
5840     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
5841     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
5842     ok(prev == NULL, "expected NULL, got %p\n", prev);
5843
5844     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
5845     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
5846
5847     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
5848     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
5849
5850     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
5851     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
5852     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
5853     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
5854
5855     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
5856     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
5857
5858     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
5859     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
5860 }
5861
5862 static void test_feature_override(void)
5863 {
5864     UINT r;
5865     REGSAM access = KEY_ALL_ACCESS;
5866
5867     if (is_process_limited())
5868     {
5869         skip("process is limited\n");
5870         return;
5871     }
5872
5873     create_test_files();
5874     create_file("msitest\\override.txt", 1000);
5875     create_file("msitest\\preselected.txt", 1000);
5876     create_file("msitest\\notpreselected.txt", 1000);
5877     create_database(msifile, fo_tables, sizeof(fo_tables) / sizeof(msi_table));
5878
5879     if (is_wow64)
5880         access |= KEY_WOW64_64KEY;
5881
5882     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5883
5884     r = MsiInstallProductA(msifile, "ADDLOCAL=override");
5885     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5886     {
5887         skip("Not enough rights to perform tests\n");
5888         goto error;
5889     }
5890     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5891
5892     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
5893     ok(!pf_exists("msitest\\preselected.txt"), "file installed\n");
5894     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
5895
5896     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5897     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5898
5899     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
5900
5901     r = MsiInstallProductA(msifile, "preselect=1");
5902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5903
5904     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
5905     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
5906     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
5907
5908     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5910
5911     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
5912     todo_wine {
5913     ok(delete_pf("msitest\\preselected.txt", TRUE), "file removed\n");
5914     ok(delete_pf("msitest", FALSE), "directory removed\n");
5915     }
5916
5917     r = MsiInstallProductA(msifile, NULL);
5918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5919
5920     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
5921     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
5922     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
5923
5924     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5926
5927     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
5928     todo_wine {
5929     ok(delete_pf("msitest\\preselected.txt", TRUE), "file removed\n");
5930     ok(delete_pf("msitest", FALSE), "directory removed\n");
5931     }
5932
5933     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest", access);
5934
5935 error:
5936     DeleteFileA("msitest\\override.txt");
5937     DeleteFileA("msitest\\preselected.txt");
5938     DeleteFileA("msitest\\notpreselected.txt");
5939     delete_test_files();
5940     DeleteFile(msifile);
5941 }
5942
5943 static void test_icon_table(void)
5944 {
5945     MSIHANDLE hdb = 0, record;
5946     LPCSTR query;
5947     UINT res;
5948     CHAR path[MAX_PATH];
5949     static const char prodcode[] = "{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}";
5950
5951     if (is_process_limited())
5952     {
5953         skip("process is limited\n");
5954         return;
5955     }
5956
5957     create_database(msifile, icon_base_tables, sizeof(icon_base_tables) / sizeof(msi_table));
5958
5959     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5960
5961     res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb);
5962     ok(res == ERROR_SUCCESS, "failed to open db: %d\n", res);
5963
5964     query = "CREATE TABLE `Icon` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL  PRIMARY KEY `Name`)";
5965     res = run_query( hdb, 0, query );
5966     ok(res == ERROR_SUCCESS, "Can't create Icon table: %d\n", res);
5967
5968     create_file("icon.ico", 100);
5969     record = MsiCreateRecord(1);
5970     res = MsiRecordSetStream(record, 1, "icon.ico");
5971     ok(res == ERROR_SUCCESS, "Failed to add stream data to record: %d\n", res);
5972
5973     query = "INSERT INTO `Icon` (`Name`, `Data`) VALUES ('testicon', ?)";
5974     res = run_query(hdb, record, query);
5975     ok(res == ERROR_SUCCESS, "Insert into Icon table failed: %d\n", res);
5976
5977     res = MsiCloseHandle(record);
5978     ok(res == ERROR_SUCCESS, "Failed to close record handle: %d\n", res);
5979     DeleteFileA("icon.ico");
5980     res = MsiDatabaseCommit(hdb);
5981     ok(res == ERROR_SUCCESS, "Failed to commit database: %d\n", res);
5982     res = MsiCloseHandle(hdb);
5983     ok(res == ERROR_SUCCESS, "Failed to close database: %d\n", res);
5984
5985     /* per-user */
5986     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
5987     if (res == ERROR_INSTALL_PACKAGE_REJECTED)
5988     {
5989         skip("Not enough rights to perform tests\n");
5990         DeleteFile(msifile);
5991         return;
5992     }
5993     ok(res == ERROR_SUCCESS, "Failed to do per-user install: %d\n", res);
5994
5995     lstrcpyA(path, APP_DATA_DIR);
5996     lstrcatA(path, "\\");
5997     lstrcatA(path, "Microsoft\\Installer\\");
5998     lstrcatA(path, prodcode);
5999     lstrcatA(path, "\\testicon");
6000     ok(file_exists(path), "Per-user icon file isn't where it's expected (%s)\n", path);
6001
6002     res = MsiInstallProductA(msifile, "REMOVE=ALL");
6003     ok(res == ERROR_SUCCESS, "Failed to uninstall per-user\n");
6004     ok(!file_exists(path), "Per-user icon file not removed (%s)\n", path);
6005
6006     /* system-wide */
6007     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
6008     ok(res == ERROR_SUCCESS, "Failed to system-wide install: %d\n", res);
6009
6010     lstrcpyA(path, WINDOWS_DIR);
6011     lstrcatA(path, "\\");
6012     lstrcatA(path, "Installer\\");
6013     lstrcatA(path, prodcode);
6014     lstrcatA(path, "\\testicon");
6015     ok(file_exists(path), "System-wide icon file isn't where it's expected (%s)\n", path);
6016
6017     res = MsiInstallProductA(msifile, "REMOVE=ALL");
6018     ok(res == ERROR_SUCCESS, "Failed to uninstall system-wide\n");
6019     ok(!file_exists(path), "System-wide icon file not removed (%s)\n", path);
6020
6021     delete_pfmsitest_files();
6022     DeleteFile(msifile);
6023 }
6024
6025 static void test_sourcedir_props(void)
6026 {
6027     UINT r;
6028
6029     if (is_process_limited())
6030     {
6031         skip("process is limited\n");
6032         return;
6033     }
6034
6035     create_test_files();
6036     create_file("msitest\\sourcedir.txt", 1000);
6037     create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
6038
6039     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6040
6041     /* full UI, no ResolveSource action */
6042     r = MsiInstallProductA(msifile, NULL);
6043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6044
6045     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6047
6048     ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
6049     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6050
6051     /* full UI, ResolveSource action */
6052     r = MsiInstallProductA(msifile, "ResolveSource=1");
6053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6054
6055     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6056     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6057
6058     ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
6059     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6060
6061     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6062
6063     /* no UI, no ResolveSource action */
6064     r = MsiInstallProductA(msifile, NULL);
6065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6066
6067     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6068     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6069
6070     ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
6071     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6072
6073     /* no UI, ResolveSource action */
6074     r = MsiInstallProductA(msifile, "ResolveSource=1");
6075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6076
6077     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6078     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6079
6080     ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
6081     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6082
6083     DeleteFileA("msitest\\sourcedir.txt");
6084     DeleteFile(msifile);
6085 }
6086
6087 static void test_package_validation(void)
6088 {
6089     UINT r;
6090
6091     if (is_process_limited())
6092     {
6093         skip("process is limited\n");
6094         return;
6095     }
6096
6097     CreateDirectoryA("msitest", NULL);
6098     create_file("msitest\\maximus", 500);
6099     create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;1033");
6100
6101     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6102
6103     r = MsiInstallProductA(msifile, NULL);
6104     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6105     {
6106         skip("Not enough rights to perform tests\n");
6107         goto error;
6108     }
6109     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6110     ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6111     ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6112
6113     DeleteFile(msifile);
6114     create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel,9999;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,1033;9999");
6121
6122     r = MsiInstallProductA(msifile, NULL);
6123     ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r);
6124
6125     DeleteFile(msifile);
6126     create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel,9999;1033");
6127
6128     r = MsiInstallProductA(msifile, NULL);
6129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6130     ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6131     ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6132
6133     DeleteFile(msifile);
6134     create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "Intel64,9999;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,1033;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), 200, "Intel32,9999;1033");
6147
6148     r = MsiInstallProductA(msifile, NULL);
6149     ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
6150
6151     DeleteFile(msifile);
6152     create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;9999");
6153
6154     r = MsiInstallProductA(msifile, NULL);
6155     ok(r == ERROR_INSTALL_LANGUAGE_UNSUPPORTED, "Expected ERROR_INSTALL_LANGUAGE_UNSUPPORTED, got %u\n", r);
6156     ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
6157     ok(!delete_pf("msitest", FALSE), "directory exists\n");
6158
6159     if (GetSystemDefaultLangID() == MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ))
6160     {
6161         DeleteFile(msifile);
6162         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;9");
6163         r = MsiInstallProductA(msifile, NULL);
6164         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6165         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6166         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6167
6168         DeleteFile(msifile);
6169         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;1024");
6170         r = MsiInstallProductA(msifile, NULL);
6171         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6172         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6173         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6174     }
6175
6176     DeleteFile(msifile);
6177     create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel32;0");
6178
6179     r = MsiInstallProductA(msifile, NULL);
6180     ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
6181     ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
6182     ok(!delete_pf("msitest", FALSE), "directory exists\n");
6183
6184     if (is_64bit && !is_wow64)
6185     {
6186         DeleteFile(msifile);
6187         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;0");
6188
6189         r = MsiInstallProductA(msifile, NULL);
6190         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6191         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6192         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6193
6194         DeleteFile(msifile);
6195         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "x64;0");
6196
6197         r = MsiInstallProductA(msifile, NULL);
6198         ok(r == ERROR_INSTALL_PACKAGE_INVALID, "Expected ERROR_INSTALL_PACKAGE_INVALID, got %u\n", r);
6199         ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
6200         ok(!delete_pf("msitest", FALSE), "directory exists\n");
6201
6202         DeleteFile(msifile);
6203         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "x64;0");
6204
6205         r = MsiInstallProductA(msifile, NULL);
6206         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6207         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6208         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6209     }
6210     else if (is_wow64)
6211     {
6212         DeleteFile(msifile);
6213         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;0");
6214
6215         r = MsiInstallProductA(msifile, NULL);
6216         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6217         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6218         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6219
6220         DeleteFile(msifile);
6221         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "x64;0");
6222
6223         r = MsiInstallProductA(msifile, NULL);
6224         ok(r == ERROR_INSTALL_PACKAGE_INVALID, "Expected ERROR_INSTALL_PACKAGE_INVALID, got %u\n", r);
6225         ok(!delete_pf_native("msitest\\maximus", TRUE), "file exists\n");
6226         ok(!delete_pf_native("msitest", FALSE), "directory exists\n");
6227
6228         DeleteFile(msifile);
6229         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "x64;0");
6230
6231         r = MsiInstallProductA(msifile, NULL);
6232         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6233         ok(delete_pf_native("msitest\\maximus", TRUE), "file exists\n");
6234         ok(delete_pf_native("msitest", FALSE), "directory exists\n");
6235     }
6236     else
6237     {
6238         DeleteFile(msifile);
6239         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "Intel;0");
6240
6241         r = MsiInstallProductA(msifile, NULL);
6242         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6243         ok(delete_pf("msitest\\maximus", TRUE), "file does not exist\n");
6244         ok(delete_pf("msitest", FALSE), "directory does not exist\n");
6245
6246         DeleteFile(msifile);
6247         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 100, "x64;0");
6248
6249         r = MsiInstallProductA(msifile, NULL);
6250         ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
6251         ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
6252         ok(!delete_pf("msitest", FALSE), "directory exists\n");
6253
6254         DeleteFile(msifile);
6255         create_database_template(msifile, pv_tables, sizeof(pv_tables)/sizeof(msi_table), 200, "x64;0");
6256
6257         r = MsiInstallProductA(msifile, NULL);
6258         ok(r == ERROR_INSTALL_PLATFORM_UNSUPPORTED, "Expected ERROR_INSTALL_PLATFORM_UNSUPPORTED, got %u\n", r);
6259         ok(!delete_pf("msitest\\maximus", TRUE), "file exists\n");
6260         ok(!delete_pf("msitest", FALSE), "directory exists\n");
6261     }
6262
6263 error:
6264     /* Delete the files in the temp (current) folder */
6265     DeleteFile(msifile);
6266     DeleteFile("msitest\\maximus");
6267     RemoveDirectory("msitest");
6268 }
6269
6270 static void test_command_line_parsing(void)
6271 {
6272     UINT r;
6273     const char *cmd;
6274
6275     if (is_process_limited())
6276     {
6277         skip("process is limited\n");
6278         return;
6279     }
6280
6281     create_test_files();
6282     create_database(msifile, cl_tables, sizeof(cl_tables)/sizeof(msi_table));
6283
6284     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6285
6286     cmd = " ";
6287     r = MsiInstallProductA(msifile, cmd);
6288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6289
6290     cmd = "=";
6291     r = MsiInstallProductA(msifile, cmd);
6292     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6293
6294     cmd = "==";
6295     r = MsiInstallProductA(msifile, cmd);
6296     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6297
6298     cmd = "one";
6299     r = MsiInstallProductA(msifile, cmd);
6300     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6301
6302     cmd = "=one";
6303     r = MsiInstallProductA(msifile, cmd);
6304     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6305
6306     cmd = "P=";
6307     r = MsiInstallProductA(msifile, cmd);
6308     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6309
6310     cmd = "  P=";
6311     r = MsiInstallProductA(msifile, cmd);
6312     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6313
6314     cmd = "P=  ";
6315     r = MsiInstallProductA(msifile, cmd);
6316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6317
6318     cmd = "P=\"";
6319     r = MsiInstallProductA(msifile, cmd);
6320     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6321
6322     cmd = "P=\"\"";
6323     r = MsiInstallProductA(msifile, cmd);
6324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6325
6326     cmd = "P=\"\"\"";
6327     r = MsiInstallProductA(msifile, cmd);
6328     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6329
6330     cmd = "P=\"\"\"\"";
6331     r = MsiInstallProductA(msifile, cmd);
6332     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6333
6334     cmd = "P=\" ";
6335     r = MsiInstallProductA(msifile, cmd);
6336     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6337
6338     cmd = "P= \"";
6339     r = MsiInstallProductA(msifile, cmd);
6340     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6341
6342     cmd = "P= \"\" ";
6343     r = MsiInstallProductA(msifile, cmd);
6344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6345
6346     cmd = "P=\"  \"";
6347     r = MsiInstallProductA(msifile, cmd);
6348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6349
6350     cmd = "P=one";
6351     r = MsiInstallProductA(msifile, cmd);
6352     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6353
6354     cmd = "P= one";
6355     r = MsiInstallProductA(msifile, cmd);
6356     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6357
6358     cmd = "P=\"one";
6359     r = MsiInstallProductA(msifile, cmd);
6360     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6361
6362     cmd = "P=one\"";
6363     r = MsiInstallProductA(msifile, cmd);
6364     todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6365
6366     cmd = "P=\"one\"";
6367     r = MsiInstallProductA(msifile, cmd);
6368     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6369
6370     cmd = "P= \"one\" ";
6371     r = MsiInstallProductA(msifile, cmd);
6372     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6373
6374     cmd = "P=\"one\"\"";
6375     r = MsiInstallProductA(msifile, cmd);
6376     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6377
6378     cmd = "P=\"\"one\"";
6379     r = MsiInstallProductA(msifile, cmd);
6380     ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6381
6382     cmd = "P=\"\"one\"\"";
6383     r = MsiInstallProductA(msifile, cmd);
6384     todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
6385
6386     cmd = "P=\"one two\"";
6387     r = MsiInstallProductA(msifile, cmd);
6388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6389
6390     cmd = "P=\"\"\"one\"\" two\"";
6391     r = MsiInstallProductA(msifile, cmd);
6392     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6393
6394     cmd = "P=\"\"\"one\"\" two\" Q=three";
6395     r = MsiInstallProductA(msifile, cmd);
6396     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6397
6398     cmd = "P=\"\" Q=\"two\"";
6399     r = MsiInstallProductA(msifile, cmd);
6400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6401
6402     cmd = "P=\"one\" Q=\"two\"";
6403     r = MsiInstallProductA(msifile, cmd);
6404     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6405
6406     cmd = "P=\"one=two\"";
6407     r = MsiInstallProductA(msifile, cmd);
6408     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6409
6410     cmd = "Q=\"\" P=\"one\"";
6411     r = MsiInstallProductA(msifile, cmd);
6412     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6413
6414     cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
6415     r = MsiInstallProductA(msifile, cmd);
6416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6417
6418     cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
6419     r = MsiInstallProductA(msifile, cmd);
6420     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6421
6422     cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
6423     r = MsiInstallProductA(msifile, cmd);
6424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6425
6426     DeleteFile(msifile);
6427     RemoveDirectory("msitest");
6428 }
6429
6430 static void test_upgrade_code(void)
6431 {
6432     UINT r;
6433
6434     if (is_process_limited())
6435     {
6436         skip("process is limited\n");
6437         return;
6438     }
6439
6440     CreateDirectoryA("msitest", NULL);
6441     create_file("msitest\\upgradecode.txt", 1000);
6442     create_database(msifile, uc_tables, sizeof(uc_tables) / sizeof(msi_table));
6443
6444     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6445
6446     r = MsiInstallProductA(msifile, NULL);
6447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6448
6449     ok(pf_exists("msitest\\upgradecode.txt"), "file not installed\n");
6450
6451     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6453
6454     ok(!delete_pf("msitest\\upgradecode.txt", TRUE), "file not removed\n");
6455     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6456
6457     DeleteFileA("msitest\\upgradecode.txt");
6458     RemoveDirectoryA("msitest");
6459     DeleteFile(msifile);
6460 }
6461
6462 static void test_MsiGetFeatureInfo(void)
6463 {
6464     UINT r;
6465     MSIHANDLE package;
6466     char title[32], help[32], path[MAX_PATH];
6467     DWORD attrs, title_len, help_len;
6468
6469     if (is_process_limited())
6470     {
6471         skip("process is limited\n");
6472         return;
6473     }
6474     create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
6475
6476     strcpy( path, CURR_DIR );
6477     strcat( path, "\\" );
6478     strcat( path, msifile );
6479
6480     r = MsiOpenPackage( path, &package );
6481     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6482     {
6483         skip("Not enough rights to perform tests\n");
6484         DeleteFileA( msifile );
6485         return;
6486     }
6487     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6488
6489     r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
6490     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
6491
6492     r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
6493     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
6494
6495     r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
6496     ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
6497
6498     r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
6499     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6500
6501     r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
6502     ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
6503
6504     title_len = help_len = 0;
6505     r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
6506     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6507     ok(title_len == 3, "expected 3, got %u\n", title_len);
6508     ok(help_len == 15, "expected 15, got %u\n", help_len);
6509
6510     title[0] = help[0] = 0;
6511     title_len = help_len = 0;
6512     r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
6513     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
6514     ok(title_len == 3, "expected 3, got %u\n", title_len);
6515     ok(help_len == 15, "expected 15, got %u\n", help_len);
6516
6517     attrs = 0;
6518     title[0] = help[0] = 0;
6519     title_len = sizeof(title);
6520     help_len = sizeof(help);
6521     r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
6522     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6523     ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
6524     ok(title_len == 3, "expected 3, got %u\n", title_len);
6525     ok(help_len == 15, "expected 15, got %u\n", help_len);
6526     ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
6527     ok(!strcmp(help, "The One Feature"), "expected \"The One Feature\", got \"%s\"\n", help);
6528
6529     attrs = 0;
6530     title[0] = help[0] = 0;
6531     title_len = sizeof(title);
6532     help_len = sizeof(help);
6533     r = MsiGetFeatureInfoA( package, "feature", &attrs, title, &title_len, help, &help_len );
6534     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6535     ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
6536     ok(!title_len, "expected 0, got %u\n", title_len);
6537     ok(!help_len, "expected 0, got %u\n", help_len);
6538     ok(!title[0], "expected \"\", got \"%s\"\n", title);
6539     ok(!help[0], "expected \"\", got \"%s\"\n", help);
6540
6541     MsiCloseHandle( package );
6542     DeleteFileA( msifile );
6543 }
6544
6545 static void test_MsiSetFeatureAttributes(void)
6546 {
6547     UINT r;
6548     DWORD attrs;
6549     char path[MAX_PATH];
6550     MSIHANDLE package;
6551
6552     if (is_process_limited())
6553     {
6554         skip("process is limited\n");
6555         return;
6556     }
6557     create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
6558
6559     strcpy( path, CURR_DIR );
6560     strcat( path, "\\" );
6561     strcat( path, msifile );
6562
6563     r = MsiOpenPackage( path, &package );
6564     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6565     {
6566         skip("Not enough rights to perform tests\n");
6567         DeleteFileA( msifile );
6568         return;
6569     }
6570     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6571
6572     r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
6573     ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
6574
6575     r = MsiDoAction( package, "CostInitialize" );
6576     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6577
6578     r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
6579     ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
6580
6581     r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
6582     ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
6583
6584     r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
6585     ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
6586
6587     r = MsiSetFeatureAttributesA( package, "One", 0 );
6588     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6589
6590     attrs = 0xdeadbeef;
6591     r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
6592     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6593     ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
6594        "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
6595
6596     r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
6597     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6598
6599     attrs = 0;
6600     r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
6601     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6602     ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
6603        "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
6604
6605     r = MsiDoAction( package, "FileCost" );
6606     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6607
6608     r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE );
6609     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6610
6611     attrs = 0;
6612     r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
6613     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6614     ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE,
6615        "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs);
6616
6617     r = MsiDoAction( package, "CostFinalize" );
6618     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
6619
6620     r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
6621     ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
6622
6623     MsiCloseHandle( package );
6624     DeleteFileA( msifile );
6625 }
6626
6627 START_TEST(install)
6628 {
6629     DWORD len;
6630     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
6631     STATEMGRSTATUS status;
6632     BOOL ret = FALSE;
6633
6634     init_functionpointers();
6635
6636     if (pIsWow64Process)
6637         pIsWow64Process(GetCurrentProcess(), &is_wow64);
6638
6639     GetCurrentDirectoryA(MAX_PATH, prev_path);
6640     GetTempPath(MAX_PATH, temp_path);
6641     SetCurrentDirectoryA(temp_path);
6642
6643     lstrcpyA(CURR_DIR, temp_path);
6644     len = lstrlenA(CURR_DIR);
6645
6646     if(len && (CURR_DIR[len - 1] == '\\'))
6647         CURR_DIR[len - 1] = 0;
6648
6649     ok(get_system_dirs(), "failed to retrieve system dirs\n");
6650     ok(get_user_dirs(), "failed to retrieve user dirs\n");
6651
6652     /* Create a restore point ourselves so we circumvent the multitude of restore points
6653      * that would have been created by all the installation and removal tests.
6654      *
6655      * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
6656      * creation of restore points.
6657      */
6658     if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
6659     {
6660         memset(&status, 0, sizeof(status));
6661         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
6662     }
6663
6664     /* Create only one log file and don't append. We have to pass something
6665      * for the log mode for this to work. The logfile needs to have an absolute
6666      * path otherwise we still end up with some extra logfiles as some tests
6667      * change the current directory.
6668      */
6669     lstrcpyA(log_file, temp_path);
6670     lstrcatA(log_file, "\\msitest.log");
6671     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
6672
6673     test_MsiInstallProduct();
6674     test_MsiSetComponentState();
6675     test_packagecoltypes();
6676     test_continuouscabs();
6677     test_caborder();
6678     test_mixedmedia();
6679     test_samesequence();
6680     test_uiLevelFlags();
6681     test_readonlyfile();
6682     test_readonlyfile_cab();
6683     test_setdirproperty();
6684     test_cabisextracted();
6685     test_concurrentinstall();
6686     test_setpropertyfolder();
6687     test_transformprop();
6688     test_currentworkingdir();
6689     test_admin();
6690     test_adminprops();
6691     test_missingcab();
6692     test_sourcefolder();
6693     test_customaction51();
6694     test_installstate();
6695     test_sourcepath();
6696     test_MsiConfigureProductEx();
6697     test_missingcomponent();
6698     test_sourcedirprop();
6699     test_adminimage();
6700     test_propcase();
6701     test_int_widths();
6702     test_shortcut();
6703     test_lastusedsource();
6704     test_preselected();
6705     test_installed_prop();
6706     test_file_in_use();
6707     test_file_in_use_cab();
6708     test_MsiSetExternalUI();
6709     test_allusers_prop();
6710     test_feature_override();
6711     test_icon_table();
6712     test_sourcedir_props();
6713     test_package_validation();
6714     test_command_line_parsing();
6715     test_upgrade_code();
6716     test_MsiGetFeatureInfo();
6717     test_MsiSetFeatureAttributes();
6718
6719     DeleteFileA(log_file);
6720
6721     if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
6722     {
6723         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
6724         if (ret)
6725             remove_restore_point(status.llSequenceNumber);
6726     }
6727     FreeLibrary(hsrclient);
6728
6729     SetCurrentDirectoryA(prev_path);
6730 }