kernel32: Add a structure to store all the information about an executable.
[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     LocalFree(usersid);
3948 }
3949
3950 static void test_publish_processcomponents(void)
3951 {
3952     UINT r;
3953     LONG res;
3954     DWORD size;
3955     HKEY comp, hkey;
3956     LPSTR usersid;
3957     CHAR val[MAX_PATH];
3958     CHAR keypath[MAX_PATH];
3959     CHAR program_files_maximus[MAX_PATH];
3960
3961     static const CHAR keyfmt[] =
3962         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3963         "UserData\\%s\\Components\\%s";
3964     static const CHAR compkey[] =
3965         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
3966
3967     if (!get_user_sid(&usersid))
3968         return;
3969
3970     CreateDirectoryA("msitest", NULL);
3971     create_file("msitest\\maximus", 500);
3972
3973     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
3974
3975     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3976
3977     /* ProcessComponents, per-user */
3978     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3980     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3981     ok(delete_pf("msitest", FALSE), "File not installed\n");
3982
3983     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
3984
3985     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
3986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3987
3988     size = MAX_PATH;
3989     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3990                            NULL, NULL, (LPBYTE)val, &size);
3991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3992
3993     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
3994     lstrcatA(program_files_maximus,"\\msitest\\maximus");
3995
3996     ok(!lstrcmpiA(val, program_files_maximus),
3997        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3998
3999     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4000     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4001
4002     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4003     RegDeleteKeyA(comp, "");
4004     RegCloseKey(comp);
4005
4006     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
4007
4008     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4010
4011     size = MAX_PATH;
4012     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4013                            NULL, NULL, (LPBYTE)val, &size);
4014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4015     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
4016        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
4017
4018     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4019     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4020
4021     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4022     RegDeleteKeyA(comp, "");
4023     RegCloseKey(comp);
4024
4025     /* ProcessComponents, machine */
4026     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
4027     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4028     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4029     ok(delete_pf("msitest", FALSE), "File not installed\n");
4030
4031     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
4032
4033     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4035
4036     size = MAX_PATH;
4037     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4038                            NULL, NULL, (LPBYTE)val, &size);
4039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4040     ok(!lstrcmpiA(val, program_files_maximus),
4041        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
4042
4043     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4044     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4045
4046     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4047     RegDeleteKeyA(comp, "");
4048     RegCloseKey(comp);
4049
4050     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
4051
4052     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4054
4055     size = MAX_PATH;
4056     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4057                            NULL, NULL, (LPBYTE)val, &size);
4058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4059     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
4060        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
4061
4062     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4063     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4064
4065     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4066     RegDeleteKeyA(comp, "");
4067     RegCloseKey(comp);
4068
4069     DeleteFile(msifile);
4070     DeleteFile("msitest\\maximus");
4071     RemoveDirectory("msitest");
4072     LocalFree(usersid);
4073 }
4074
4075 static void test_publish(void)
4076 {
4077     UINT r;
4078     LONG res;
4079     HKEY uninstall, prodkey;
4080     INSTALLSTATE state;
4081     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4082     char date[MAX_PATH];
4083     char temp[MAX_PATH];
4084
4085     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
4086
4087     if (!pMsiQueryComponentStateA)
4088     {
4089         win_skip("MsiQueryComponentStateA is not available\n");
4090         return;
4091     }
4092
4093     get_date_str(date);
4094     GetTempPath(MAX_PATH, temp);
4095
4096     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
4097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4098
4099     CreateDirectoryA("msitest", NULL);
4100     create_file("msitest\\maximus", 500);
4101
4102     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4103
4104     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4105
4106     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4107     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4108
4109     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4110     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4111
4112     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4113     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4114
4115     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4116                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4117     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4118     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4119
4120     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4121     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4122
4123     /* nothing published */
4124     r = MsiInstallProductA(msifile, NULL);
4125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4126     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4127     ok(pf_exists("msitest"), "File not installed\n");
4128
4129     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4130     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4131
4132     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4133     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4134
4135     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4136     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4137
4138     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4139                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4140     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4141     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4142
4143     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4144     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4145
4146     /* PublishProduct and RegisterProduct */
4147     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
4148     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4149     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4150     ok(pf_exists("msitest"), "File not installed\n");
4151
4152     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4153     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4154
4155     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4156     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4157
4158     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4159     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4160
4161     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4162                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4163     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4164     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4165
4166     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4168
4169     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4170     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4171     CHECK_REG_STR(prodkey, "InstallDate", date);
4172     CHECK_REG_STR(prodkey, "InstallSource", temp);
4173     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4174     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4175     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4176     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4177     CHECK_REG_STR(prodkey, "Comments", NULL);
4178     CHECK_REG_STR(prodkey, "Contact", NULL);
4179     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4180     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4181     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4182     CHECK_REG_STR(prodkey, "Readme", NULL);
4183     CHECK_REG_STR(prodkey, "Size", NULL);
4184     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4185     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4186     CHECK_REG_DWORD(prodkey, "Language", 1033);
4187     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4188     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4189     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4190     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4191     todo_wine
4192     {
4193         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4194     }
4195
4196     RegCloseKey(prodkey);
4197
4198     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4200     ok(pf_exists("msitest\\maximus"), "File deleted\n");
4201     ok(pf_exists("msitest"), "File deleted\n");
4202
4203     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4204     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4205
4206     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4207     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4208
4209     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4210     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4211
4212     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4213                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4214     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4215     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4216
4217     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4218     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4219
4220     /* complete install */
4221     r = MsiInstallProductA(msifile, "FULL=1");
4222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4223     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4224     ok(pf_exists("msitest"), "File not installed\n");
4225
4226     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4227     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4228
4229     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4230     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4231
4232     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4233     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4234
4235     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4236                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4237     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4238     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4239
4240     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4242
4243     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4244     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4245     CHECK_REG_STR(prodkey, "InstallDate", date);
4246     CHECK_REG_STR(prodkey, "InstallSource", temp);
4247     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4248     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4249     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4250     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4251     CHECK_REG_STR(prodkey, "Comments", NULL);
4252     CHECK_REG_STR(prodkey, "Contact", NULL);
4253     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4254     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4255     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4256     CHECK_REG_STR(prodkey, "Readme", NULL);
4257     CHECK_REG_STR(prodkey, "Size", NULL);
4258     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4259     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4260     CHECK_REG_DWORD(prodkey, "Language", 1033);
4261     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4262     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4263     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4264     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4265     todo_wine
4266     {
4267         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4268     }
4269
4270     RegCloseKey(prodkey);
4271
4272     /* no UnpublishFeatures */
4273     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4274     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4275     ok(!pf_exists("msitest\\maximus"), "File deleted\n");
4276     todo_wine
4277     {
4278         ok(!pf_exists("msitest"), "File deleted\n");
4279     }
4280
4281     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4282     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4283
4284     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4285     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4286
4287     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4288     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4289
4290     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4291                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4292     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4293     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4294
4295     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4296     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4297
4298     /* complete install */
4299     r = MsiInstallProductA(msifile, "FULL=1");
4300     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4301     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4302     ok(pf_exists("msitest"), "File not installed\n");
4303
4304     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4305     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4306
4307     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4308     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4309
4310     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4311     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4312
4313     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4314                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4315     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4316     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4317
4318     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4320
4321     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4322     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4323     CHECK_REG_STR(prodkey, "InstallDate", date);
4324     CHECK_REG_STR(prodkey, "InstallSource", temp);
4325     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4326     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4327     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4328     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4329     CHECK_REG_STR(prodkey, "Comments", NULL);
4330     CHECK_REG_STR(prodkey, "Contact", NULL);
4331     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4332     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4333     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4334     CHECK_REG_STR(prodkey, "Readme", NULL);
4335     CHECK_REG_STR(prodkey, "Size", NULL);
4336     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4337     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4338     CHECK_REG_DWORD(prodkey, "Language", 1033);
4339     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4340     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4341     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4342     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4343     todo_wine
4344     {
4345         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4346     }
4347
4348     RegCloseKey(prodkey);
4349
4350     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
4351     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
4352     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4353     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
4354     ok(pf_exists("msitest"), "File deleted\n");
4355
4356     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4357     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4358
4359     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4360     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4361
4362     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4363     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4364
4365     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4366                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4367     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4368     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4369
4370     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4372
4373     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4374     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4375     CHECK_REG_STR(prodkey, "InstallDate", date);
4376     CHECK_REG_STR(prodkey, "InstallSource", temp);
4377     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4378     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4379     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4380     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4381     CHECK_REG_STR(prodkey, "Comments", NULL);
4382     CHECK_REG_STR(prodkey, "Contact", NULL);
4383     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4384     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4385     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4386     CHECK_REG_STR(prodkey, "Readme", NULL);
4387     CHECK_REG_STR(prodkey, "Size", NULL);
4388     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4389     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4390     CHECK_REG_DWORD(prodkey, "Language", 1033);
4391     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4392     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4393     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4394     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4395     todo_wine
4396     {
4397         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4398     }
4399
4400     RegCloseKey(prodkey);
4401
4402     /* complete install */
4403     r = MsiInstallProductA(msifile, "FULL=1");
4404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4405     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4406     ok(pf_exists("msitest"), "File not installed\n");
4407
4408     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4409     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4410
4411     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4412     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4413
4414     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4415     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4416
4417     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4418                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4420     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4421
4422     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4424
4425     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4426     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4427     CHECK_REG_STR(prodkey, "InstallDate", date);
4428     CHECK_REG_STR(prodkey, "InstallSource", temp);
4429     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4430     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4431     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4432     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4433     CHECK_REG_STR(prodkey, "Comments", NULL);
4434     CHECK_REG_STR(prodkey, "Contact", NULL);
4435     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4436     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4437     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4438     CHECK_REG_STR(prodkey, "Readme", NULL);
4439     CHECK_REG_STR(prodkey, "Size", NULL);
4440     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4441     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4442     CHECK_REG_DWORD(prodkey, "Language", 1033);
4443     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4444     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4445     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4446     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4447     todo_wine
4448     {
4449         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
4450     }
4451
4452     RegCloseKey(prodkey);
4453
4454     /* UnpublishFeatures, both features removed */
4455     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
4456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4457     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4458     todo_wine
4459     {
4460         ok(!pf_exists("msitest"), "File not deleted\n");
4461     }
4462
4463     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4464     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4465
4466     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4467     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4468
4469     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4470     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4471
4472     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4473                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4474     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4475     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4476
4477     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4478     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4479
4480     /* complete install */
4481     r = MsiInstallProductA(msifile, "FULL=1");
4482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4483     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4484     ok(pf_exists("msitest"), "File not installed\n");
4485
4486     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4487     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4488
4489     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4490     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4491
4492     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4493     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4494
4495     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4496                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4497     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4498     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4499
4500     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4501     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4502
4503     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4504     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4505     CHECK_REG_STR(prodkey, "InstallDate", date);
4506     CHECK_REG_STR(prodkey, "InstallSource", temp);
4507     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4508     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4509     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4510     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4511     CHECK_REG_STR(prodkey, "Comments", NULL);
4512     CHECK_REG_STR(prodkey, "Contact", NULL);
4513     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4514     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4515     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4516     CHECK_REG_STR(prodkey, "Readme", NULL);
4517     CHECK_REG_STR(prodkey, "Size", NULL);
4518     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4519     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4520     CHECK_REG_DWORD(prodkey, "Language", 1033);
4521     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4522     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4523     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4524     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4525     todo_wine
4526     {
4527         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4528     }
4529
4530     RegCloseKey(prodkey);
4531
4532     /* complete uninstall */
4533     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4534     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4535     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4536     todo_wine
4537     {
4538         ok(!pf_exists("msitest"), "File not deleted\n");
4539     }
4540
4541     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4542     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4543
4544     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4545     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4546
4547     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4548     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4549
4550     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4551                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4552     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4553     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4554
4555     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4556     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4557
4558     /* make sure 'Program Files\msitest' is removed */
4559     delete_pfmsitest_files();
4560
4561     RegCloseKey(uninstall);
4562     DeleteFile(msifile);
4563     DeleteFile("msitest\\maximus");
4564     RemoveDirectory("msitest");
4565 }
4566
4567 static void test_publishsourcelist(void)
4568 {
4569     UINT r;
4570     DWORD size;
4571     CHAR value[MAX_PATH];
4572     CHAR path[MAX_PATH];
4573     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4574
4575     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
4576     {
4577         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
4578         return;
4579     }
4580
4581     CreateDirectoryA("msitest", NULL);
4582     create_file("msitest\\maximus", 500);
4583
4584     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4585
4586     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4587
4588     r = MsiInstallProductA(msifile, NULL);
4589     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4590     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4591     ok(pf_exists("msitest"), "File not installed\n");
4592
4593     /* nothing published */
4594     size = MAX_PATH;
4595     lstrcpyA(value, "aaa");
4596     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4597                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4598     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4599     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4600     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4601
4602     size = MAX_PATH;
4603     lstrcpyA(value, "aaa");
4604     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4605                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4606     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4607     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4608     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4609
4610     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4611     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4612     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4613     ok(pf_exists("msitest"), "File not installed\n");
4614
4615     /* after RegisterProduct */
4616     size = MAX_PATH;
4617     lstrcpyA(value, "aaa");
4618     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4619                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4620     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4621     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4622     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4623
4624     size = MAX_PATH;
4625     lstrcpyA(value, "aaa");
4626     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4627                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4628     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4629     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4630     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4631
4632     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4634     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4635     ok(pf_exists("msitest"), "File not installed\n");
4636
4637     /* after ProcessComponents */
4638     size = MAX_PATH;
4639     lstrcpyA(value, "aaa");
4640     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4641                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4642     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4643     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4644     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4645
4646     size = MAX_PATH;
4647     lstrcpyA(value, "aaa");
4648     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4649                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4650     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4651     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4652     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4653
4654     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4655     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4656     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4657     ok(pf_exists("msitest"), "File not installed\n");
4658
4659     /* after PublishFeatures */
4660     size = MAX_PATH;
4661     lstrcpyA(value, "aaa");
4662     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4663                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4664     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4665     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4666     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4667
4668     size = MAX_PATH;
4669     lstrcpyA(value, "aaa");
4670     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4671                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4672     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4673     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4674     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4675
4676     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4678     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4679     ok(pf_exists("msitest"), "File not installed\n");
4680
4681     /* after PublishProduct */
4682     size = MAX_PATH;
4683     lstrcpyA(value, "aaa");
4684     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4685                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4686     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4687     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
4688     ok(size == 11, "Expected 11, got %d\n", size);
4689
4690     size = MAX_PATH;
4691     lstrcpyA(value, "aaa");
4692     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4693                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
4694     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4695     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4696     ok(size == 0, "Expected 0, got %d\n", size);
4697
4698     size = MAX_PATH;
4699     lstrcpyA(value, "aaa");
4700     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4701                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
4702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4703     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4704     ok(size == 0, "Expected 0, got %d\n", size);
4705
4706     lstrcpyA(path, CURR_DIR);
4707     lstrcatA(path, "\\");
4708
4709     size = MAX_PATH;
4710     lstrcpyA(value, "aaa");
4711     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4712                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4714     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4715     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4716
4717     size = MAX_PATH;
4718     lstrcpyA(value, "aaa");
4719     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4720                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
4721     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4722     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
4723     ok(size == 1, "Expected 1, got %d\n", size);
4724
4725     size = MAX_PATH;
4726     lstrcpyA(value, "aaa");
4727     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4728                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4729     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4730     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4731     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4732
4733     size = MAX_PATH;
4734     lstrcpyA(value, "aaa");
4735     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4736                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
4737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4738     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4739     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4740
4741     size = MAX_PATH;
4742     lstrcpyA(value, "aaa");
4743     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4744                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
4745     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4746     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4747     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4748
4749     /* complete uninstall */
4750     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4751     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4752     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4753     todo_wine
4754     {
4755         ok(!pf_exists("msitest"), "File not deleted\n");
4756     }
4757
4758     /* make sure 'Program Files\msitest' is removed */
4759     delete_pfmsitest_files();
4760
4761     DeleteFile(msifile);
4762     DeleteFile("msitest\\maximus");
4763     RemoveDirectory("msitest");
4764 }
4765
4766 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
4767 {
4768     MSIHANDLE hview = 0;
4769     UINT r;
4770
4771     r = MsiDatabaseOpenView(hdb, query, &hview);
4772     if(r != ERROR_SUCCESS)
4773         return r;
4774
4775     r = MsiViewExecute(hview, hrec);
4776     if(r == ERROR_SUCCESS)
4777         r = MsiViewClose(hview);
4778     MsiCloseHandle(hview);
4779     return r;
4780 }
4781
4782 static void set_transform_summary_info(void)
4783 {
4784     UINT r;
4785     MSIHANDLE suminfo = 0;
4786
4787     /* build summary info */
4788     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
4789     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
4790
4791     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
4792     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
4793
4794     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
4795                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
4796                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
4797                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
4798     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
4799
4800     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
4801     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
4802
4803     r = MsiSummaryInfoPersist(suminfo);
4804     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
4805
4806     r = MsiCloseHandle(suminfo);
4807     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
4808 }
4809
4810 static void generate_transform(void)
4811 {
4812     MSIHANDLE hdb1, hdb2;
4813     LPCSTR query;
4814     UINT r;
4815
4816     /* start with two identical databases */
4817     CopyFile(msifile, msifile2, FALSE);
4818
4819     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
4820     ok(r == ERROR_SUCCESS , "Failed to create database\n");
4821
4822     r = MsiDatabaseCommit(hdb1);
4823     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
4824
4825     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
4826     ok(r == ERROR_SUCCESS , "Failed to create database\n");
4827
4828     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
4829     r = run_query(hdb1, 0, query);
4830     ok(r == ERROR_SUCCESS, "failed to add property\n");
4831
4832     /* database needs to be committed */
4833     MsiDatabaseCommit(hdb1);
4834
4835     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
4836     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
4837
4838 #if 0  /* not implemented in wine yet */
4839     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
4840     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4841 #endif
4842
4843     MsiCloseHandle(hdb1);
4844     MsiCloseHandle(hdb2);
4845 }
4846
4847 /* data for generating a transform */
4848
4849 /* tables transform names - encoded as they would be in an msi database file */
4850 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
4851 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
4852 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
4853
4854 /* data in each table */
4855 static const char data1[] = /* _StringData */
4856     "propval";  /* all the strings squashed together */
4857
4858 static const WCHAR data2[] = { /* _StringPool */
4859 /*  len, refs */
4860     0,   0,    /* string 0 ''     */
4861     4,   1,    /* string 1 'prop' */
4862     3,   1,    /* string 2 'val'  */
4863 };
4864
4865 static const WCHAR data3[] = { /* Property */
4866     0x0201, 0x0001, 0x0002,
4867 };
4868
4869 static const struct {
4870     LPCWSTR name;
4871     const void *data;
4872     DWORD size;
4873 } table_transform_data[] =
4874 {
4875     { name1, data1, sizeof data1 - 1 },
4876     { name2, data2, sizeof data2 },
4877     { name3, data3, sizeof data3 },
4878 };
4879
4880 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
4881
4882 static void generate_transform_manual(void)
4883 {
4884     IStorage *stg = NULL;
4885     IStream *stm;
4886     WCHAR name[0x20];
4887     HRESULT r;
4888     DWORD i, count;
4889     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
4890
4891     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
4892
4893     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
4894
4895     r = StgCreateDocfile(name, mode, 0, &stg);
4896     ok(r == S_OK, "failed to create storage\n");
4897     if (!stg)
4898         return;
4899
4900     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
4901     ok(r == S_OK, "failed to set storage type\n");
4902
4903     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
4904     {
4905         r = IStorage_CreateStream(stg, table_transform_data[i].name,
4906                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4907         if (FAILED(r))
4908         {
4909             ok(0, "failed to create stream %08x\n", r);
4910             continue;
4911         }
4912
4913         r = IStream_Write(stm, table_transform_data[i].data,
4914                           table_transform_data[i].size, &count);
4915         if (FAILED(r) || count != table_transform_data[i].size)
4916             ok(0, "failed to write stream\n");
4917         IStream_Release(stm);
4918     }
4919
4920     IStorage_Release(stg);
4921
4922     set_transform_summary_info();
4923 }
4924
4925 static void test_transformprop(void)
4926 {
4927     UINT r;
4928
4929     CreateDirectoryA("msitest", NULL);
4930     create_file("msitest\\augustus", 500);
4931
4932     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
4933
4934     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4935
4936     r = MsiInstallProductA(msifile, NULL);
4937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4938     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4939     ok(!delete_pf("msitest", FALSE), "File installed\n");
4940
4941     if (0)
4942         generate_transform();
4943     else
4944         generate_transform_manual();
4945
4946     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
4947     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4948     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4949     ok(delete_pf("msitest", FALSE), "File not installed\n");
4950
4951     /* Delete the files in the temp (current) folder */
4952     DeleteFile(msifile);
4953     DeleteFile(msifile2);
4954     DeleteFile(mstfile);
4955     DeleteFile("msitest\\augustus");
4956     RemoveDirectory("msitest");
4957 }
4958
4959 static void test_currentworkingdir(void)
4960 {
4961     UINT r;
4962     CHAR drive[MAX_PATH], path[MAX_PATH];
4963     LPSTR ptr;
4964
4965     CreateDirectoryA("msitest", NULL);
4966     create_file("msitest\\augustus", 500);
4967
4968     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
4969
4970     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4971
4972     CreateDirectoryA("diffdir", NULL);
4973     SetCurrentDirectoryA("diffdir");
4974
4975     sprintf(path, "..\\%s", msifile);
4976     r = MsiInstallProductA(path, NULL);
4977     todo_wine
4978     {
4979         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
4980         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4981         ok(!delete_pf("msitest", FALSE), "File installed\n");
4982     }
4983
4984     sprintf(path, "%s\\%s", CURR_DIR, msifile);
4985     r = MsiInstallProductA(path, NULL);
4986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4987     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4988     ok(delete_pf("msitest", FALSE), "File not installed\n");
4989
4990     lstrcpyA(drive, CURR_DIR);
4991     drive[2] = '\\';
4992     drive[3] = '\0';
4993     SetCurrentDirectoryA(drive);
4994
4995     lstrcpy(path, CURR_DIR);
4996     if (path[lstrlenA(path) - 1] != '\\')
4997         lstrcatA(path, "\\");
4998     lstrcatA(path, msifile);
4999     ptr = strchr(path, ':');
5000     ptr +=2;
5001
5002     r = MsiInstallProductA(ptr, NULL);
5003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5004     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5005     ok(delete_pf("msitest", FALSE), "File not installed\n");
5006
5007     SetCurrentDirectoryA(CURR_DIR);
5008
5009     DeleteFile(msifile);
5010     DeleteFile("msitest\\augustus");
5011     RemoveDirectory("msitest");
5012     RemoveDirectory("diffdir");
5013 }
5014
5015 static void set_admin_summary_info(const CHAR *name)
5016 {
5017     MSIHANDLE db, summary;
5018     UINT r;
5019
5020     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
5021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5022
5023     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
5024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5025
5026     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
5027     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5028
5029     /* write the summary changes back to the stream */
5030     r = MsiSummaryInfoPersist(summary);
5031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5032
5033     MsiCloseHandle(summary);
5034
5035     r = MsiDatabaseCommit(db);
5036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5037
5038     MsiCloseHandle(db);
5039 }
5040
5041 static void test_admin(void)
5042 {
5043     UINT r;
5044
5045     CreateDirectoryA("msitest", NULL);
5046     create_file("msitest\\augustus", 500);
5047
5048     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
5049     set_admin_summary_info(msifile);
5050
5051     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5052
5053     r = MsiInstallProductA(msifile, NULL);
5054     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5055     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5056     ok(!delete_pf("msitest", FALSE), "File installed\n");
5057     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
5058     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
5059
5060     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
5061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5062     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5063     ok(!delete_pf("msitest", FALSE), "File installed\n");
5064     todo_wine
5065     {
5066         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
5067         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
5068     }
5069
5070     DeleteFile(msifile);
5071     DeleteFile("msitest\\augustus");
5072     RemoveDirectory("msitest");
5073 }
5074
5075 static void set_admin_property_stream(LPCSTR file)
5076 {
5077     IStorage *stg;
5078     IStream *stm;
5079     WCHAR fileW[MAX_PATH];
5080     HRESULT hr;
5081     DWORD count;
5082     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
5083
5084     /* AdminProperties */
5085     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
5086     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
5087         'M','y','P','r','o','p','=','4','2',0};
5088
5089     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
5090
5091     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
5092     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5093     if (!stg)
5094         return;
5095
5096     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
5097     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5098
5099     hr = IStream_Write(stm, data, sizeof(data), &count);
5100     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5101
5102     IStream_Release(stm);
5103     IStorage_Release(stg);
5104 }
5105
5106 static void test_adminprops(void)
5107 {
5108     UINT r;
5109
5110     CreateDirectoryA("msitest", NULL);
5111     create_file("msitest\\augustus", 500);
5112
5113     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
5114     set_admin_summary_info(msifile);
5115     set_admin_property_stream(msifile);
5116
5117     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5118
5119     r = MsiInstallProductA(msifile, NULL);
5120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5121     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5122     ok(delete_pf("msitest", FALSE), "File installed\n");
5123
5124     DeleteFile(msifile);
5125     DeleteFile("msitest\\augustus");
5126     RemoveDirectory("msitest");
5127 }
5128
5129 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
5130 {
5131     CHAR path[MAX_PATH];
5132
5133     lstrcpyA(path, PROG_FILES_DIR);
5134     lstrcatA(path, "\\");
5135     lstrcatA(path, file);
5136
5137     if (is_file)
5138         create_file_data(path, data, 500);
5139     else
5140         CreateDirectoryA(path, NULL);
5141 }
5142
5143 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
5144
5145 static void test_removefiles(void)
5146 {
5147     UINT r;
5148
5149     CreateDirectoryA("msitest", NULL);
5150     create_file("msitest\\hydrogen", 500);
5151     create_file("msitest\\helium", 500);
5152     create_file("msitest\\lithium", 500);
5153
5154     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
5155
5156     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5157
5158     r = MsiInstallProductA(msifile, NULL);
5159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5160     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5161     ok(!pf_exists("msitest\\helium"), "File installed\n");
5162     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5163     ok(pf_exists("msitest"), "File not installed\n");
5164
5165     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5166     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5167     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
5168     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
5169     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
5170     ok(delete_pf("msitest", FALSE), "File deleted\n");
5171
5172     create_pf("msitest", FALSE);
5173     create_pf("msitest\\hydrogen", TRUE);
5174     create_pf("msitest\\helium", TRUE);
5175     create_pf("msitest\\lithium", TRUE);
5176
5177     r = MsiInstallProductA(msifile, NULL);
5178     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5179     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5180     ok(pf_exists("msitest\\helium"), "File not installed\n");
5181     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5182     ok(pf_exists("msitest"), "File not installed\n");
5183
5184     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5186     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
5187     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
5188     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
5189     ok(delete_pf("msitest", FALSE), "File deleted\n");
5190
5191     create_pf("msitest", FALSE);
5192     create_pf("msitest\\furlong", TRUE);
5193     create_pf("msitest\\firkin", TRUE);
5194     create_pf("msitest\\fortnight", TRUE);
5195     create_pf("msitest\\becquerel", TRUE);
5196     create_pf("msitest\\dioptre", TRUE);
5197     create_pf("msitest\\attoparsec", TRUE);
5198     create_pf("msitest\\storeys", TRUE);
5199     create_pf("msitest\\block", TRUE);
5200     create_pf("msitest\\siriometer", TRUE);
5201     create_pf("msitest\\cabout", FALSE);
5202     create_pf("msitest\\cabout\\blocker", TRUE);
5203
5204     r = MsiInstallProductA(msifile, NULL);
5205     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5206     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5207     ok(!pf_exists("msitest\\helium"), "File installed\n");
5208     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5209     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
5210     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
5211     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
5212     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
5213     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
5214     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
5215     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
5216     ok(!pf_exists("msitest\\block"), "File not deleted\n");
5217     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
5218     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
5219     ok(pf_exists("msitest"), "File not installed\n");
5220
5221     create_pf("msitest\\furlong", TRUE);
5222     create_pf("msitest\\firkin", TRUE);
5223     create_pf("msitest\\fortnight", TRUE);
5224     create_pf("msitest\\storeys", TRUE);
5225     create_pf("msitest\\block", TRUE);
5226     create_pf("msitest\\siriometer", TRUE);
5227
5228     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5230     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
5231     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
5232     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
5233     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
5234     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
5235     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
5236     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
5237     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
5238     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
5239     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
5240     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
5241     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
5242     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
5243     ok(pf_exists("msitest"), "Directory deleted\n");
5244
5245     r = MsiInstallProductA(msifile, NULL);
5246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5247     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
5248     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
5249     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
5250     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
5251     ok(pf_exists("msitest"), "Directory deleted\n");
5252
5253     delete_pf("msitest\\cabout\\blocker", TRUE);
5254
5255     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5257     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
5258     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
5259
5260     DeleteFile(msifile);
5261     DeleteFile("msitest\\hydrogen");
5262     DeleteFile("msitest\\helium");
5263     DeleteFile("msitest\\lithium");
5264     RemoveDirectory("msitest");
5265 }
5266
5267 static void test_movefiles(void)
5268 {
5269     UINT r;
5270     char props[MAX_PATH];
5271
5272     CreateDirectoryA("msitest", NULL);
5273     create_file("msitest\\augustus", 100);
5274     create_file("cameroon", 100);
5275     create_file("djibouti", 100);
5276     create_file("egypt", 100);
5277     create_file("finland", 100);
5278     create_file("gambai", 100);
5279     create_file("honduras", 100);
5280     create_file("msitest\\india", 100);
5281     create_file("japan", 100);
5282     create_file("kenya", 100);
5283     CreateDirectoryA("latvia", NULL);
5284     create_file("nauru", 100);
5285     create_file("peru", 100);
5286     create_file("apple", 100);
5287     create_file("application", 100);
5288     create_file("ape", 100);
5289     create_file("foo", 100);
5290     create_file("fao", 100);
5291     create_file("fbod", 100);
5292     create_file("budding", 100);
5293     create_file("buddy", 100);
5294     create_file("bud", 100);
5295     create_file("bar", 100);
5296     create_file("bur", 100);
5297     create_file("bird", 100);
5298
5299     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
5300
5301     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5302
5303     /* if the source or dest property is not a full path,
5304      * windows tries to access it as a network resource
5305      */
5306
5307     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
5308             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
5309             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
5310
5311     r = MsiInstallProductA(msifile, props);
5312     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5313     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5314     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
5315     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
5316     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
5317     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
5318     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
5319     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
5320     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
5321     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
5322     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
5323     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
5324     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
5325     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
5326     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
5327     /* either apple or application will be moved depending on directory order */
5328     if (!delete_pf("msitest\\apple", TRUE))
5329         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
5330     else
5331         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
5332     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
5333     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
5334     /* either fao or foo will be moved depending on directory order */
5335     if (delete_pf("msitest\\foo", TRUE))
5336         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
5337     else
5338         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
5339     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
5340     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
5341     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
5342     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
5343     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
5344     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
5345     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
5346     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
5347     ok(delete_pf("msitest", FALSE), "File not installed\n");
5348     ok(DeleteFileA("cameroon"), "File moved\n");
5349     ok(!DeleteFileA("djibouti"), "File not moved\n");
5350     ok(DeleteFileA("egypt"), "File moved\n");
5351     ok(DeleteFileA("finland"), "File moved\n");
5352     ok(DeleteFileA("gambai"), "File moved\n");
5353     ok(!DeleteFileA("honduras"), "File not moved\n");
5354     ok(DeleteFileA("msitest\\india"), "File moved\n");
5355     ok(DeleteFileA("japan"), "File moved\n");
5356     ok(!DeleteFileA("kenya"), "File not moved\n");
5357     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
5358     ok(!DeleteFileA("nauru"), "File not moved\n");
5359     ok(!DeleteFileA("peru"), "File not moved\n");
5360     ok(!DeleteFileA("apple"), "File not moved\n");
5361     ok(!DeleteFileA("application"), "File not moved\n");
5362     ok(DeleteFileA("ape"), "File moved\n");
5363     ok(!DeleteFileA("foo"), "File not moved\n");
5364     ok(!DeleteFileA("fao"), "File not moved\n");
5365     ok(DeleteFileA("fbod"), "File moved\n");
5366     ok(!DeleteFileA("budding"), "File not moved\n");
5367     ok(!DeleteFileA("buddy"), "File not moved\n");
5368     ok(DeleteFileA("bud"), "File moved\n");
5369     ok(!DeleteFileA("bar"), "File not moved\n");
5370     ok(!DeleteFileA("bur"), "File not moved\n");
5371     ok(DeleteFileA("bird"), "File moved\n");
5372
5373     DeleteFile("msitest\\augustus");
5374     RemoveDirectory("msitest");
5375     DeleteFile(msifile);
5376 }
5377
5378 static void test_missingcab(void)
5379 {
5380     UINT r;
5381
5382     CreateDirectoryA("msitest", NULL);
5383     create_file("msitest\\augustus", 500);
5384     create_file("maximus", 500);
5385
5386     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
5387
5388     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5389
5390     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
5391
5392     create_pf("msitest", FALSE);
5393     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
5394
5395     r = MsiInstallProductA(msifile, NULL);
5396     ok(r == ERROR_SUCCESS ||
5397        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
5398        "Expected ERROR_SUCCESS, got %u\n", r);
5399     if (r == ERROR_SUCCESS)
5400     {
5401       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5402       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5403     }
5404     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
5405     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
5406     ok(delete_pf("msitest", FALSE), "File not installed\n");
5407
5408     create_pf("msitest", FALSE);
5409     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
5410     create_pf("msitest\\gaius", TRUE);
5411
5412     r = MsiInstallProductA(msifile, "GAIUS=1");
5413     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5414     todo_wine
5415     {
5416         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
5417         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5418     }
5419     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
5420     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
5421     ok(delete_pf("msitest", FALSE), "File not installed\n");
5422
5423     DeleteFile("msitest\\augustus");
5424     RemoveDirectory("msitest");
5425     DeleteFile("maximus");
5426     DeleteFile("test1.cab");
5427     DeleteFile(msifile);
5428 }
5429
5430 static void test_duplicatefiles(void)
5431 {
5432     UINT r;
5433
5434     CreateDirectoryA("msitest", NULL);
5435     create_file("msitest\\maximus", 500);
5436     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
5437
5438     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5439
5440     /* fails if the destination folder is not a valid property */
5441
5442     r = MsiInstallProductA(msifile, NULL);
5443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5444     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5445     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
5446     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
5447     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
5448     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
5449     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
5450     ok(delete_pf("msitest", FALSE), "File not installed\n");
5451
5452     DeleteFile("msitest\\maximus");
5453     RemoveDirectory("msitest");
5454     DeleteFile(msifile);
5455 }
5456
5457 static void test_writeregistryvalues(void)
5458 {
5459     UINT r;
5460     LONG res;
5461     HKEY hkey;
5462     DWORD type, size;
5463     CHAR path[MAX_PATH];
5464
5465     CreateDirectoryA("msitest", NULL);
5466     create_file("msitest\\augustus", 500);
5467
5468     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
5469
5470     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5471
5472     r = MsiInstallProductA(msifile, NULL);
5473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5474     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5475     ok(delete_pf("msitest", FALSE), "File installed\n");
5476
5477     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
5478     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5479
5480     size = MAX_PATH;
5481     type = REG_MULTI_SZ;
5482     memset(path, 'a', MAX_PATH);
5483     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
5484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5485     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
5486     ok(size == 15, "Expected 15, got %d\n", size);
5487     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5488
5489     DeleteFile(msifile);
5490     DeleteFile("msitest\\augustus");
5491     RemoveDirectory("msitest");
5492
5493     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
5494     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
5495 }
5496
5497 static void test_sourcefolder(void)
5498 {
5499     UINT r;
5500
5501     CreateDirectoryA("msitest", NULL);
5502     create_file("augustus", 500);
5503
5504     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
5505
5506     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5507
5508     r = MsiInstallProductA(msifile, NULL);
5509     ok(r == ERROR_INSTALL_FAILURE,
5510        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5511     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5512     todo_wine
5513     {
5514         ok(!delete_pf("msitest", FALSE), "File installed\n");
5515     }
5516
5517     RemoveDirectoryA("msitest");
5518
5519     r = MsiInstallProductA(msifile, NULL);
5520     ok(r == ERROR_INSTALL_FAILURE,
5521        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5522     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5523     todo_wine
5524     {
5525         ok(!delete_pf("msitest", FALSE), "File installed\n");
5526     }
5527
5528     DeleteFile(msifile);
5529     DeleteFile("augustus");
5530 }
5531
5532 static void test_customaction51(void)
5533 {
5534     UINT r;
5535
5536     CreateDirectoryA("msitest", NULL);
5537     create_file("msitest\\augustus", 500);
5538
5539     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
5540
5541     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5542
5543     r = MsiInstallProductA(msifile, NULL);
5544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5545     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5546     ok(delete_pf("msitest", FALSE), "File installed\n");
5547
5548     DeleteFile(msifile);
5549     DeleteFile("msitest\\augustus");
5550     RemoveDirectory("msitest");
5551 }
5552
5553 static void test_installstate(void)
5554 {
5555     UINT r;
5556
5557     CreateDirectoryA("msitest", NULL);
5558     create_file("msitest\\alpha", 500);
5559     create_file("msitest\\beta", 500);
5560     create_file("msitest\\gamma", 500);
5561     create_file("msitest\\theta", 500);
5562     create_file("msitest\\delta", 500);
5563     create_file("msitest\\epsilon", 500);
5564     create_file("msitest\\zeta", 500);
5565     create_file("msitest\\iota", 500);
5566     create_file("msitest\\eta", 500);
5567     create_file("msitest\\kappa", 500);
5568     create_file("msitest\\lambda", 500);
5569     create_file("msitest\\mu", 500);
5570
5571     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
5572
5573     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5574
5575     r = MsiInstallProductA(msifile, NULL);
5576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5577     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5578     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5579     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
5580     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5581     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5582     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5583     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
5584     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5585     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5586     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5587     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5588     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5589     ok(delete_pf("msitest", FALSE), "File not installed\n");
5590
5591     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
5592     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5593     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5594     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5595     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
5596     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5597     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5598     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
5599     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
5600     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5601     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
5602     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5603     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5604     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5605     ok(delete_pf("msitest", FALSE), "File not installed\n");
5606
5607     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
5608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5609     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5610     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5611     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
5612     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5613     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5614     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5615     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
5616     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5617     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5618     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5619     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5620     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5621     ok(delete_pf("msitest", FALSE), "File not installed\n");
5622
5623     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
5624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5625     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
5626     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5627     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
5628     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
5629     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5630     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5631     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
5632     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5633     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5634     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5635     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5636     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5637     ok(!delete_pf("msitest", FALSE), "File installed\n");
5638
5639     DeleteFile(msifile);
5640     DeleteFile("msitest\\alpha");
5641     DeleteFile("msitest\\beta");
5642     DeleteFile("msitest\\gamma");
5643     DeleteFile("msitest\\theta");
5644     DeleteFile("msitest\\delta");
5645     DeleteFile("msitest\\epsilon");
5646     DeleteFile("msitest\\zeta");
5647     DeleteFile("msitest\\iota");
5648     DeleteFile("msitest\\eta");
5649     DeleteFile("msitest\\kappa");
5650     DeleteFile("msitest\\lambda");
5651     DeleteFile("msitest\\mu");
5652     RemoveDirectory("msitest");
5653 }
5654
5655 struct sourcepathmap
5656 {
5657     BOOL sost; /* shortone\shorttwo */
5658     BOOL solt; /* shortone\longtwo */
5659     BOOL lost; /* longone\shorttwo */
5660     BOOL lolt; /* longone\longtwo */
5661     BOOL soste; /* shortone\shorttwo source exists */
5662     BOOL solte; /* shortone\longtwo source exists */
5663     BOOL loste; /* longone\shorttwo source exists */
5664     BOOL lolte; /* longone\longtwo source exists */
5665     UINT err;
5666     DWORD size;
5667 } spmap[256] =
5668 {
5669     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5670     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5671     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5672     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5673     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5674     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5675     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5676     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5677     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5678     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5679     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5680     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5681     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5682     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5683     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5684     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5685     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5686     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5687     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5688     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5689     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5690     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5691     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5692     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5693     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5694     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5695     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5696     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5697     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5698     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5699     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5700     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5701     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5702     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5703     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5704     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5705     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5706     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5707     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5708     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5709     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5710     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5711     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5712     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5713     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5714     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5715     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5716     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5717     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5718     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5719     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5720     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5721     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5722     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5723     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5724     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5725     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5726     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5727     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5728     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5729     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5730     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5731     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5732     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5733     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5734     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5735     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5736     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5737     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5738     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5739     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5740     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5741     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5742     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5743     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5744     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5745     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5746     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5747     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5748     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5749     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5750     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5751     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5752     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5753     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5754     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5755     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5756     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5757     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5758     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5759     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5760     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5761     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5762     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5763     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5764     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5765     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5766     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5767     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5768     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5769     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5770     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5771     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5772     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5773     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5774     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5775     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5776     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5777     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5778     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5779     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5780     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5781     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5782     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5783     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5784     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5785     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5786     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5787     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5788     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5789     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5790     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5791     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5792     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5793     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5794     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5795     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5796     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5797     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5798     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5799     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5800     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5801     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5802     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5803     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5804     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5805     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5806     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5807     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5808     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5809     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5810     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5811     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5812     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5813     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5814     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5815     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5816     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5817     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5818     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5819     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5820     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5821     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5822     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5823     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5824     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5825     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5826     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5827     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5828     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5829     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5830     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5831     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5832     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5833     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5834     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5835     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5836     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5837     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5838     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5839     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5840     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5841     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5842     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5843     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5844     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5845     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5846     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5847     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5848     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5849     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5850     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5851     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5852     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5853     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5854     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5855     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5856     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5857     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5858     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5859     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5860     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5861     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5862     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5863     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5864     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5865     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5866     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5867     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5868     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5869     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5870     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5871     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5872     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5873     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5874     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5875     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5876     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5877     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5878     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5879     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5880     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5881     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5882     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5883     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5884     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5885     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5886     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5887     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5888     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5889     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5890     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5891     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5892     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5893     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5894     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5895     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5896     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5897     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5898     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5899     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5900     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5901     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5902     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5903     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5904     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5905     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5906     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5907     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5908     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5909     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5910     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5911     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5912     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5913     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5914     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5915     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5916     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5917     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5918     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5919     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5920     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5921     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5922     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5923     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5924     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5925 };
5926
5927 static DWORD get_pf_file_size(LPCSTR file)
5928 {
5929     CHAR path[MAX_PATH];
5930     HANDLE hfile;
5931     DWORD size;
5932
5933     lstrcpyA(path, PROG_FILES_DIR);
5934     lstrcatA(path, "\\");
5935     lstrcatA(path, file);
5936
5937     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
5938     if (hfile == INVALID_HANDLE_VALUE)
5939         return 0;
5940
5941     size = GetFileSize(hfile, NULL);
5942     CloseHandle(hfile);
5943     return size;
5944 }
5945
5946 static void test_sourcepath(void)
5947 {
5948     UINT r, i;
5949
5950     if (!winetest_interactive)
5951     {
5952         skip("Run in interactive mode to run source path tests.\n");
5953         return;
5954     }
5955
5956     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
5957
5958     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5959
5960     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
5961     {
5962         if (spmap[i].sost)
5963         {
5964             CreateDirectoryA("shortone", NULL);
5965             CreateDirectoryA("shortone\\shorttwo", NULL);
5966         }
5967
5968         if (spmap[i].solt)
5969         {
5970             CreateDirectoryA("shortone", NULL);
5971             CreateDirectoryA("shortone\\longtwo", NULL);
5972         }
5973
5974         if (spmap[i].lost)
5975         {
5976             CreateDirectoryA("longone", NULL);
5977             CreateDirectoryA("longone\\shorttwo", NULL);
5978         }
5979
5980         if (spmap[i].lolt)
5981         {
5982             CreateDirectoryA("longone", NULL);
5983             CreateDirectoryA("longone\\longtwo", NULL);
5984         }
5985
5986         if (spmap[i].soste)
5987             create_file("shortone\\shorttwo\\augustus", 50);
5988         if (spmap[i].solte)
5989             create_file("shortone\\longtwo\\augustus", 100);
5990         if (spmap[i].loste)
5991             create_file("longone\\shorttwo\\augustus", 150);
5992         if (spmap[i].lolte)
5993             create_file("longone\\longtwo\\augustus", 200);
5994
5995         r = MsiInstallProductA(msifile, NULL);
5996         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
5997         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
5998            "%d: Expected %d, got %d\n", i, spmap[i].size,
5999            get_pf_file_size("msitest\\augustus"));
6000
6001         if (r == ERROR_SUCCESS)
6002         {
6003             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
6004             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
6005         }
6006         else
6007         {
6008             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
6009             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
6010         }
6011
6012         DeleteFileA("shortone\\shorttwo\\augustus");
6013         DeleteFileA("shortone\\longtwo\\augustus");
6014         DeleteFileA("longone\\shorttwo\\augustus");
6015         DeleteFileA("longone\\longtwo\\augustus");
6016         RemoveDirectoryA("shortone\\shorttwo");
6017         RemoveDirectoryA("shortone\\longtwo");
6018         RemoveDirectoryA("longone\\shorttwo");
6019         RemoveDirectoryA("longone\\longtwo");
6020         RemoveDirectoryA("shortone");
6021         RemoveDirectoryA("longone");
6022     }
6023
6024     DeleteFileA(msifile);
6025 }
6026
6027 static void test_MsiConfigureProductEx(void)
6028 {
6029     UINT r;
6030     LONG res;
6031     DWORD type, size;
6032     HKEY props, source;
6033     CHAR keypath[MAX_PATH * 2];
6034     CHAR localpack[MAX_PATH];
6035
6036     if (on_win9x)
6037     {
6038         win_skip("Different registry keys on Win9x and WinMe\n");
6039         return;
6040     }
6041
6042     CreateDirectoryA("msitest", NULL);
6043     create_file("msitest\\hydrogen", 500);
6044     create_file("msitest\\helium", 500);
6045     create_file("msitest\\lithium", 500);
6046
6047     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6048
6049     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6050
6051     /* NULL szProduct */
6052     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
6053                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6054     ok(r == ERROR_INVALID_PARAMETER,
6055        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6056
6057     /* empty szProduct */
6058     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
6059                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6060     ok(r == ERROR_INVALID_PARAMETER,
6061        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6062
6063     /* garbage szProduct */
6064     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
6065                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6066     ok(r == ERROR_INVALID_PARAMETER,
6067        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6068
6069     /* guid without brackets */
6070     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6071                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6072                                "PROPVAR=42");
6073     ok(r == ERROR_INVALID_PARAMETER,
6074        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6075
6076     /* guid with brackets */
6077     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6078                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6079                                "PROPVAR=42");
6080     ok(r == ERROR_UNKNOWN_PRODUCT,
6081        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6082
6083     /* same length as guid, but random */
6084     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
6085                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6086                                "PROPVAR=42");
6087     ok(r == ERROR_UNKNOWN_PRODUCT,
6088        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6089
6090     /* product not installed yet */
6091     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6092                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6093                                "PROPVAR=42");
6094     ok(r == ERROR_UNKNOWN_PRODUCT,
6095        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6096
6097     /* install the product, per-user unmanaged */
6098     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
6099     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6100     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6101     ok(pf_exists("msitest\\helium"), "File not installed\n");
6102     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6103     ok(pf_exists("msitest"), "File not installed\n");
6104
6105     /* product is installed per-user managed, remove it */
6106     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6107                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6108                                "PROPVAR=42");
6109     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6110     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6111     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6112     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6113     todo_wine
6114     {
6115         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6116     }
6117
6118     /* product has been removed */
6119     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6120                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6121                                "PROPVAR=42");
6122     ok(r == ERROR_UNKNOWN_PRODUCT,
6123        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
6124
6125     /* install the product, machine */
6126     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6128     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6129     ok(pf_exists("msitest\\helium"), "File not installed\n");
6130     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6131     ok(pf_exists("msitest"), "File not installed\n");
6132
6133     /* product is installed machine, remove it */
6134     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6135                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6136                                "PROPVAR=42");
6137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6138     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6139     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6140     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6141     todo_wine
6142     {
6143         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6144     }
6145
6146     /* product has been removed */
6147     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6148                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6149                                "PROPVAR=42");
6150     ok(r == ERROR_UNKNOWN_PRODUCT,
6151        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
6152
6153     /* install the product, machine */
6154     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6155     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6156     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6157     ok(pf_exists("msitest\\helium"), "File not installed\n");
6158     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6159     ok(pf_exists("msitest"), "File not installed\n");
6160
6161     DeleteFileA(msifile);
6162
6163     /* local msifile is removed */
6164     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6165                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6166                                "PROPVAR=42");
6167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6168     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6169     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6170     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6171     todo_wine
6172     {
6173         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6174     }
6175
6176     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6177
6178     /* install the product, machine */
6179     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6180     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6181     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6182     ok(pf_exists("msitest\\helium"), "File not installed\n");
6183     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6184     ok(pf_exists("msitest"), "File not installed\n");
6185
6186     DeleteFileA(msifile);
6187
6188     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
6189     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
6190     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
6191
6192     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
6193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6194
6195     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
6196                          (const BYTE *)"C:\\idontexist.msi", 18);
6197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6198
6199     /* LocalPackage is used to find the cached msi package */
6200     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6201                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6202                                "PROPVAR=42");
6203     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
6204        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
6205     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6206     ok(pf_exists("msitest\\helium"), "File not installed\n");
6207     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6208     ok(pf_exists("msitest"), "File not installed\n");
6209
6210     RegCloseKey(props);
6211     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6212
6213     /* LastUsedSource (local msi package) can be used as a last resort */
6214     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6215                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6216                                "PROPVAR=42");
6217     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6218     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6219     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6220     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6221     todo_wine
6222     {
6223         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6224     }
6225
6226     /* install the product, machine */
6227     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6229     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6230     ok(pf_exists("msitest\\helium"), "File not installed\n");
6231     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6232     ok(pf_exists("msitest"), "File not installed\n");
6233
6234     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
6235     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
6236     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
6237
6238     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
6239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6240
6241     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
6242                          (const BYTE *)"C:\\idontexist.msi", 18);
6243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6244
6245     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
6246     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
6247
6248     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
6249     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6250
6251     type = REG_SZ;
6252     size = MAX_PATH;
6253     res = RegQueryValueExA(source, "PackageName", NULL, &type,
6254                            (LPBYTE)localpack, &size);
6255     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6256
6257     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
6258                          (const BYTE *)"idontexist.msi", 15);
6259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6260
6261     /* SourceList is altered */
6262     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6263                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6264                                "PROPVAR=42");
6265     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
6266        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
6267     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6268     ok(pf_exists("msitest\\helium"), "File not installed\n");
6269     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6270     ok(pf_exists("msitest"), "File not installed\n");
6271
6272     /* restore the SourceList */
6273     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
6274                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
6275     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6276
6277     /* finally remove the product */
6278     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6279                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6280                                "PROPVAR=42");
6281     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6282     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6283     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6284     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6285     todo_wine
6286     {
6287         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6288     }
6289
6290     DeleteFileA(msifile);
6291     RegCloseKey(source);
6292     RegCloseKey(props);
6293     DeleteFileA("msitest\\hydrogen");
6294     DeleteFileA("msitest\\helium");
6295     DeleteFileA("msitest\\lithium");
6296     RemoveDirectoryA("msitest");
6297 }
6298
6299 static void test_missingcomponent(void)
6300 {
6301     UINT r;
6302
6303     CreateDirectoryA("msitest", NULL);
6304     create_file("msitest\\hydrogen", 500);
6305     create_file("msitest\\helium", 500);
6306     create_file("msitest\\lithium", 500);
6307     create_file("beryllium", 500);
6308
6309     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
6310
6311     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6312
6313     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
6314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6315     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6316     ok(pf_exists("msitest\\helium"), "File not installed\n");
6317     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6318     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
6319     ok(pf_exists("msitest"), "File not installed\n");
6320
6321     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
6322     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6323     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6324     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6325     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6326     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
6327     todo_wine
6328     {
6329         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6330     }
6331
6332     DeleteFileA(msifile);
6333     DeleteFileA("msitest\\hydrogen");
6334     DeleteFileA("msitest\\helium");
6335     DeleteFileA("msitest\\lithium");
6336     DeleteFileA("beryllium");
6337     RemoveDirectoryA("msitest");
6338 }
6339
6340 static void test_sourcedirprop(void)
6341 {
6342     UINT r;
6343     CHAR props[MAX_PATH];
6344
6345     CreateDirectoryA("msitest", NULL);
6346     create_file("msitest\\augustus", 500);
6347
6348     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6349
6350     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6351
6352     r = MsiInstallProductA(msifile, NULL);
6353     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6354     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6355     ok(delete_pf("msitest", FALSE), "File installed\n");
6356
6357     DeleteFile("msitest\\augustus");
6358     RemoveDirectory("msitest");
6359
6360     CreateDirectoryA("altsource", NULL);
6361     CreateDirectoryA("altsource\\msitest", NULL);
6362     create_file("altsource\\msitest\\augustus", 500);
6363
6364     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
6365
6366     r = MsiInstallProductA(msifile, props);
6367     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6368     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6369     ok(delete_pf("msitest", FALSE), "File installed\n");
6370
6371     DeleteFile(msifile);
6372     DeleteFile("altsource\\msitest\\augustus");
6373     RemoveDirectory("altsource\\msitest");
6374     RemoveDirectory("altsource");
6375 }
6376
6377 static void test_adminimage(void)
6378 {
6379     UINT r;
6380
6381     CreateDirectoryA("msitest", NULL);
6382     CreateDirectoryA("msitest\\first", NULL);
6383     CreateDirectoryA("msitest\\second", NULL);
6384     CreateDirectoryA("msitest\\cabout", NULL);
6385     CreateDirectoryA("msitest\\cabout\\new", NULL);
6386     create_file("msitest\\one.txt", 100);
6387     create_file("msitest\\first\\two.txt", 100);
6388     create_file("msitest\\second\\three.txt", 100);
6389     create_file("msitest\\cabout\\four.txt", 100);
6390     create_file("msitest\\cabout\\new\\five.txt", 100);
6391     create_file("msitest\\filename", 100);
6392     create_file("msitest\\service.exe", 100);
6393
6394     create_database_wordcount(msifile, ai_tables,
6395                               sizeof(ai_tables) / sizeof(msi_table),
6396                               msidbSumInfoSourceTypeAdminImage);
6397
6398     r = MsiInstallProductA(msifile, NULL);
6399     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6400
6401     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6402     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6403     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6404     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6405     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6406     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6407     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6408     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6409     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
6410     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6411     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6412     ok(delete_pf("msitest", FALSE), "File not installed\n");
6413
6414     DeleteFileA("msitest.msi");
6415     DeleteFileA("msitest\\cabout\\new\\five.txt");
6416     DeleteFileA("msitest\\cabout\\four.txt");
6417     DeleteFileA("msitest\\second\\three.txt");
6418     DeleteFileA("msitest\\first\\two.txt");
6419     DeleteFileA("msitest\\one.txt");
6420     DeleteFileA("msitest\\service.exe");
6421     DeleteFileA("msitest\\filename");
6422     RemoveDirectoryA("msitest\\cabout\\new");
6423     RemoveDirectoryA("msitest\\cabout");
6424     RemoveDirectoryA("msitest\\second");
6425     RemoveDirectoryA("msitest\\first");
6426     RemoveDirectoryA("msitest");
6427 }
6428
6429 static void test_propcase(void)
6430 {
6431     UINT r;
6432
6433     CreateDirectoryA("msitest", NULL);
6434     create_file("msitest\\augustus", 500);
6435
6436     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
6437
6438     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6439
6440     r = MsiInstallProductA(msifile, "MyProp=42");
6441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6442     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6443     ok(delete_pf("msitest", FALSE), "File not installed\n");
6444
6445     DeleteFile(msifile);
6446     DeleteFile("msitest\\augustus");
6447     RemoveDirectory("msitest");
6448 }
6449
6450 static void test_int_widths( void )
6451 {
6452     static const char int0[] = "int0\ni0\nint0\tint0\n1";
6453     static const char int1[] = "int1\ni1\nint1\tint1\n1";
6454     static const char int2[] = "int2\ni2\nint2\tint2\n1";
6455     static const char int3[] = "int3\ni3\nint3\tint3\n1";
6456     static const char int4[] = "int4\ni4\nint4\tint4\n1";
6457     static const char int5[] = "int5\ni5\nint5\tint5\n1";
6458     static const char int8[] = "int8\ni8\nint8\tint8\n1";
6459
6460     static const struct
6461     {
6462         const char  *data;
6463         unsigned int size;
6464         UINT         ret;
6465     }
6466     tests[] =
6467     {
6468         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
6469         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
6470         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
6471         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
6472         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
6473         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
6474         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
6475     };
6476
6477     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
6478     MSIHANDLE db;
6479     UINT r, i;
6480
6481     GetTempPathA(MAX_PATH, tmpdir);
6482     CreateDirectoryA(tmpdir, NULL);
6483
6484     strcpy(msitable, tmpdir);
6485     strcat(msitable, "\\msitable.idt");
6486
6487     strcpy(msidb, tmpdir);
6488     strcat(msidb, "\\msitest.msi");
6489
6490     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
6491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6492
6493     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
6494     {
6495         write_file(msitable, tests[i].data, tests[i].size);
6496
6497         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
6498         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
6499
6500         r = MsiDatabaseCommit(db);
6501         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6502         DeleteFileA(msitable);
6503     }
6504
6505     MsiCloseHandle(db);
6506     DeleteFileA(msidb);
6507     RemoveDirectoryA(tmpdir);
6508 }
6509
6510 static void test_shortcut(void)
6511 {
6512     UINT r;
6513     HRESULT hr;
6514
6515     create_test_files();
6516     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
6517
6518     r = MsiInstallProductA(msifile, NULL);
6519     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6520
6521     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
6522     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
6523
6524     r = MsiInstallProductA(msifile, NULL);
6525     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6526
6527     CoUninitialize();
6528
6529     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
6530     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
6531
6532     r = MsiInstallProductA(msifile, NULL);
6533     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6534
6535     CoUninitialize();
6536
6537     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
6538     delete_pf("msitest\\cabout\\new", FALSE);
6539     delete_pf("msitest\\cabout\\four.txt", TRUE);
6540     delete_pf("msitest\\cabout", FALSE);
6541     delete_pf("msitest\\changed\\three.txt", TRUE);
6542     delete_pf("msitest\\changed", FALSE);
6543     delete_pf("msitest\\first\\two.txt", TRUE);
6544     delete_pf("msitest\\first", FALSE);
6545     delete_pf("msitest\\filename", TRUE);
6546     delete_pf("msitest\\one.txt", TRUE);
6547     delete_pf("msitest\\service.exe", TRUE);
6548     delete_pf("msitest\\Shortcut.lnk", TRUE);
6549     delete_pf("msitest", FALSE);
6550     delete_test_files();
6551 }
6552
6553 static void test_envvar(void)
6554 {
6555     UINT r;
6556     HKEY env;
6557     LONG res;
6558     DWORD type, size;
6559     char buffer[16];
6560
6561     if (on_win9x)
6562     {
6563         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
6564         return;
6565     }
6566
6567     create_test_files();
6568     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
6569
6570     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
6571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6572
6573     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
6574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6575
6576     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
6577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6578
6579     r = MsiInstallProductA(msifile, NULL);
6580     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6581
6582     type = REG_NONE;
6583     size = sizeof(buffer);
6584     buffer[0] = 0;
6585     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
6586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6587     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
6588     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
6589
6590     res = RegDeleteValueA(env, "MSITESTVAR1");
6591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6592
6593     type = REG_NONE;
6594     size = sizeof(buffer);
6595     buffer[0] = 0;
6596     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
6597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6598     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
6599     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
6600
6601     res = RegDeleteValueA(env, "MSITESTVAR2");
6602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6603
6604     res = RegDeleteValueA(env, "MSITESTVAR3");
6605     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6606
6607     res = RegDeleteValueA(env, "MSITESTVAR4");
6608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6609
6610     RegCloseKey(env);
6611
6612     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
6613     delete_pf("msitest\\cabout\\new", FALSE);
6614     delete_pf("msitest\\cabout\\four.txt", TRUE);
6615     delete_pf("msitest\\cabout", FALSE);
6616     delete_pf("msitest\\changed\\three.txt", TRUE);
6617     delete_pf("msitest\\changed", FALSE);
6618     delete_pf("msitest\\first\\two.txt", TRUE);
6619     delete_pf("msitest\\first", FALSE);
6620     delete_pf("msitest\\filename", TRUE);
6621     delete_pf("msitest\\one.txt", TRUE);
6622     delete_pf("msitest\\service.exe", TRUE);
6623     delete_pf("msitest", FALSE);
6624     delete_test_files();
6625 }
6626
6627 static void test_preselected(void)
6628 {
6629     UINT r;
6630
6631     create_test_files();
6632     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
6633
6634     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
6635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6636
6637     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
6638     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
6639     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
6640     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
6641     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
6642     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
6643     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
6644     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
6645     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
6646     todo_wine ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
6647     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
6648     todo_wine ok(delete_pf("msitest", FALSE), "File not installed\n");
6649
6650     r = MsiInstallProductA(msifile, NULL);
6651     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6652
6653     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6654     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6655     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6656     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6657     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6658     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6659     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6660     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6661     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6662     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
6663     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6664     ok(delete_pf("msitest", FALSE), "File not installed\n");
6665     delete_test_files();
6666 }
6667
6668 static void test_installed_prop(void)
6669 {
6670     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
6671     UINT r;
6672
6673     create_test_files();
6674     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
6675
6676     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6677
6678     r = MsiInstallProductA(msifile, "FULL=1");
6679     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6680
6681     r = MsiInstallProductA(msifile, "FULL=1");
6682     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6683
6684     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
6685     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6686
6687     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6688     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6689     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6690     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6691     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6692     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6693     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6694     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6695     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6696     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
6697     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6698     ok(delete_pf("msitest", FALSE), "File not installed\n");
6699
6700     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6702
6703     delete_test_files();
6704 }
6705
6706 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
6707 static char rename_ops[]      = "PendingFileRenameOperations";
6708
6709 static void process_pending_renames(HKEY hkey)
6710 {
6711     char *buf, *src, *dst;
6712     DWORD size;
6713     LONG ret;
6714
6715     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
6716     buf = HeapAlloc(GetProcessHeap(), 0, size);
6717     buf[0] = 0;
6718
6719     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
6720     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
6721     ok(strstr(buf, "msitest\\maximus") != NULL, "Unexpected value \"%s\"\n", buf);
6722
6723     for (src = buf; *src; src = dst + strlen(dst) + 1)
6724     {
6725         DWORD flags = MOVEFILE_COPY_ALLOWED;
6726
6727         dst = src + strlen(src) + 1;
6728         if (*dst == '!')
6729         {
6730             flags |= MOVEFILE_REPLACE_EXISTING;
6731             dst++;
6732         }
6733         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
6734         if (*dst)
6735         {
6736             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
6737             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
6738         }
6739         else
6740             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
6741     }
6742     HeapFree(GetProcessHeap(), 0, buf);
6743     RegDeleteValueA(hkey, rename_ops);
6744 }
6745
6746 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
6747 {
6748     DWORD len, data_len = strlen(data);
6749     HANDLE handle;
6750     char buf[128];
6751
6752     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
6753     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
6754
6755     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
6756     {
6757         CloseHandle(handle);
6758         return !memcmp(buf, data, data_len);
6759     }
6760     CloseHandle(handle);
6761     return FALSE;
6762 }
6763
6764 static void test_file_in_use(void)
6765 {
6766     UINT r;
6767     DWORD size;
6768     HANDLE file;
6769     HKEY hkey;
6770     char path[MAX_PATH];
6771
6772     if (on_win9x)
6773     {
6774         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
6775         return;
6776     }
6777
6778     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
6779     if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size))
6780     {
6781         skip("Pending file rename operations, skipping test\n");
6782         return;
6783     }
6784
6785     CreateDirectoryA("msitest", NULL);
6786     create_file("msitest\\maximus", 500);
6787     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
6788
6789     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6790
6791     lstrcpy(path, PROG_FILES_DIR);
6792     lstrcat(path, "\\msitest");
6793     CreateDirectoryA(path, NULL);
6794
6795     lstrcat(path, "\\maximus");
6796     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
6797
6798     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
6799     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
6800     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
6801     CloseHandle(file);
6802     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
6803
6804     process_pending_renames(hkey);
6805     RegCloseKey(hkey);
6806
6807     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
6808     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
6809     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
6810
6811     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6812     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6813
6814     delete_test_files();
6815 }
6816
6817 static void test_file_in_use_cab(void)
6818 {
6819     UINT r;
6820     DWORD size;
6821     HANDLE file;
6822     HKEY hkey;
6823     char path[MAX_PATH];
6824
6825     if (on_win9x)
6826     {
6827         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
6828         return;
6829     }
6830
6831     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
6832     if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size))
6833     {
6834         skip("Pending file rename operations, skipping test\n");
6835         return;
6836     }
6837
6838     CreateDirectoryA("msitest", NULL);
6839     create_file("maximus", 500);
6840     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6841     DeleteFile("maximus");
6842
6843     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
6844
6845     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6846
6847     lstrcpy(path, PROG_FILES_DIR);
6848     lstrcat(path, "\\msitest");
6849     CreateDirectoryA(path, NULL);
6850
6851     lstrcat(path, "\\maximus");
6852     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
6853
6854     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
6855     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
6856     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
6857     CloseHandle(file);
6858     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
6859
6860     process_pending_renames(hkey);
6861     RegCloseKey(hkey);
6862
6863     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
6864     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
6865     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
6866
6867     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6868     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6869
6870     delete_cab_files();
6871     delete_test_files();
6872 }
6873
6874 START_TEST(install)
6875 {
6876     DWORD len;
6877     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
6878     STATEMGRSTATUS status;
6879     BOOL ret = FALSE;
6880
6881     init_functionpointers();
6882
6883     on_win9x = check_win9x();
6884
6885     GetCurrentDirectoryA(MAX_PATH, prev_path);
6886     GetTempPath(MAX_PATH, temp_path);
6887     SetCurrentDirectoryA(temp_path);
6888
6889     lstrcpyA(CURR_DIR, temp_path);
6890     len = lstrlenA(CURR_DIR);
6891
6892     if(len && (CURR_DIR[len - 1] == '\\'))
6893         CURR_DIR[len - 1] = 0;
6894
6895     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
6896
6897     /* Create a restore point ourselves so we circumvent the multitude of restore points
6898      * that would have been created by all the installation and removal tests.
6899      */
6900     if (pSRSetRestorePointA)
6901     {
6902         memset(&status, 0, sizeof(status));
6903         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
6904     }
6905
6906     /* Create only one log file and don't append. We have to pass something
6907      * for the log mode for this to work. The logfile needs to have an absolute
6908      * path otherwise we still end up with some extra logfiles as some tests
6909      * change the current directory.
6910      */
6911     lstrcpyA(log_file, temp_path);
6912     lstrcatA(log_file, "\\msitest.log");
6913     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
6914
6915     test_MsiInstallProduct();
6916     test_MsiSetComponentState();
6917     test_packagecoltypes();
6918     test_continuouscabs();
6919     test_caborder();
6920     test_mixedmedia();
6921     test_samesequence();
6922     test_uiLevelFlags();
6923     test_readonlyfile();
6924     test_readonlyfile_cab();
6925     test_setdirproperty();
6926     test_cabisextracted();
6927     test_concurrentinstall();
6928     test_setpropertyfolder();
6929     test_publish_registerproduct();
6930     test_publish_publishproduct();
6931     test_publish_publishfeatures();
6932     test_publish_registeruser();
6933     test_publish_processcomponents();
6934     test_publish();
6935     test_publishsourcelist();
6936     test_transformprop();
6937     test_currentworkingdir();
6938     test_admin();
6939     test_adminprops();
6940     test_removefiles();
6941     test_movefiles();
6942     test_missingcab();
6943     test_duplicatefiles();
6944     test_writeregistryvalues();
6945     test_sourcefolder();
6946     test_customaction51();
6947     test_installstate();
6948     test_sourcepath();
6949     test_MsiConfigureProductEx();
6950     test_missingcomponent();
6951     test_sourcedirprop();
6952     test_adminimage();
6953     test_propcase();
6954     test_int_widths();
6955     test_shortcut();
6956     test_envvar();
6957     test_lastusedsource();
6958     test_preselected();
6959     test_installed_prop();
6960     test_file_in_use();
6961     test_file_in_use_cab();
6962
6963     DeleteFileA(log_file);
6964
6965     if (pSRSetRestorePointA && ret)
6966     {
6967         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
6968         if (ret)
6969             remove_restore_point(status.llSequenceNumber);
6970     }
6971     FreeLibrary(hsrclient);
6972
6973     SetCurrentDirectoryA(prev_path);
6974 }