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