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