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