shdocvw: Support URLs passed by reference in WebBrowser_Navigate2.
[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     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
4390
4391     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
4392     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
4393
4394     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
4395                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
4396                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
4397                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
4398     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
4399
4400     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
4401     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
4402
4403     r = MsiSummaryInfoPersist(suminfo);
4404     todo_wine
4405     {
4406         ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
4407     }
4408
4409     r = MsiCloseHandle(suminfo);
4410     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
4411 }
4412
4413 static void generate_transform(void)
4414 {
4415     MSIHANDLE hdb1, hdb2;
4416     LPCSTR query;
4417     UINT r;
4418
4419     /* start with two identical databases */
4420     CopyFile(msifile, msifile2, FALSE);
4421
4422     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
4423     ok(r == ERROR_SUCCESS , "Failed to create database\n");
4424
4425     r = MsiDatabaseCommit(hdb1);
4426     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
4427
4428     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
4429     ok(r == ERROR_SUCCESS , "Failed to create database\n");
4430
4431     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
4432     r = run_query(hdb1, 0, query);
4433     ok(r == ERROR_SUCCESS, "failed to add property\n");
4434
4435     /* database needs to be committed */
4436     MsiDatabaseCommit(hdb1);
4437
4438     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
4439     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
4440
4441 #if 0  /* not implemented in wine yet */
4442     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
4443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4444 #endif
4445
4446     MsiCloseHandle(hdb1);
4447     MsiCloseHandle(hdb2);
4448 }
4449
4450 /* data for generating a transform */
4451
4452 /* tables transform names - encoded as they would be in an msi database file */
4453 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
4454 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
4455 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
4456
4457 /* data in each table */
4458 static const char data1[] = /* _StringData */
4459     "propval";  /* all the strings squashed together */
4460
4461 static const WCHAR data2[] = { /* _StringPool */
4462 /*  len, refs */
4463     0,   0,    /* string 0 ''     */
4464     4,   1,    /* string 1 'prop' */
4465     3,   1,    /* string 2 'val'  */
4466 };
4467
4468 static const WCHAR data3[] = { /* Property */
4469     0x0201, 0x0001, 0x0002,
4470 };
4471
4472 static const struct {
4473     LPCWSTR name;
4474     const void *data;
4475     DWORD size;
4476 } table_transform_data[] =
4477 {
4478     { name1, data1, sizeof data1 - 1 },
4479     { name2, data2, sizeof data2 },
4480     { name3, data3, sizeof data3 },
4481 };
4482
4483 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
4484
4485 static void generate_transform_manual(void)
4486 {
4487     IStorage *stg = NULL;
4488     IStream *stm;
4489     WCHAR name[0x20];
4490     HRESULT r;
4491     DWORD i, count;
4492     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
4493
4494     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
4495
4496     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
4497
4498     r = StgCreateDocfile(name, mode, 0, &stg);
4499     ok(r == S_OK, "failed to create storage\n");
4500     if (!stg)
4501         return;
4502
4503     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
4504     ok(r == S_OK, "failed to set storage type\n");
4505
4506     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
4507     {
4508         r = IStorage_CreateStream(stg, table_transform_data[i].name,
4509                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4510         if (FAILED(r))
4511         {
4512             ok(0, "failed to create stream %08x\n", r);
4513             continue;
4514         }
4515
4516         r = IStream_Write(stm, table_transform_data[i].data,
4517                           table_transform_data[i].size, &count);
4518         if (FAILED(r) || count != table_transform_data[i].size)
4519             ok(0, "failed to write stream\n");
4520         IStream_Release(stm);
4521     }
4522
4523     IStorage_Release(stg);
4524
4525     set_transform_summary_info();
4526 }
4527
4528 static void test_transformprop(void)
4529 {
4530     UINT r;
4531
4532     CreateDirectoryA("msitest", NULL);
4533     create_file("msitest\\augustus", 500);
4534
4535     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
4536
4537     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4538
4539     r = MsiInstallProductA(msifile, NULL);
4540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4541     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4542     ok(!delete_pf("msitest", FALSE), "File installed\n");
4543
4544     if (0)
4545         generate_transform();
4546     else
4547         generate_transform_manual();
4548
4549     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
4550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4551     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4552     ok(delete_pf("msitest", FALSE), "File not installed\n");
4553
4554     /* Delete the files in the temp (current) folder */
4555     DeleteFile(msifile);
4556     DeleteFile(msifile2);
4557     DeleteFile(mstfile);
4558     DeleteFile("msitest\\augustus");
4559     RemoveDirectory("msitest");
4560 }
4561
4562 static void test_currentworkingdir(void)
4563 {
4564     UINT r;
4565     CHAR drive[MAX_PATH], path[MAX_PATH];
4566     LPSTR ptr;
4567
4568     CreateDirectoryA("msitest", NULL);
4569     create_file("msitest\\augustus", 500);
4570
4571     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
4572
4573     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4574
4575     CreateDirectoryA("diffdir", NULL);
4576     SetCurrentDirectoryA("diffdir");
4577
4578     sprintf(path, "..\\%s", msifile);
4579     r = MsiInstallProductA(path, NULL);
4580     todo_wine
4581     {
4582         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
4583         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4584         ok(!delete_pf("msitest", FALSE), "File installed\n");
4585     }
4586
4587     sprintf(path, "%s\\%s", CURR_DIR, msifile);
4588     r = MsiInstallProductA(path, NULL);
4589     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4590     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4591     ok(delete_pf("msitest", FALSE), "File not installed\n");
4592
4593     lstrcpyA(drive, CURR_DIR);
4594     drive[2] = '\\';
4595     drive[3] = '\0';
4596     SetCurrentDirectoryA(drive);
4597
4598     lstrcpy(path, CURR_DIR);
4599     if (path[lstrlenA(path) - 1] != '\\')
4600         lstrcatA(path, "\\");
4601     lstrcatA(path, msifile);
4602     ptr = strchr(path, ':');
4603     ptr +=2;
4604
4605     r = MsiInstallProductA(ptr, NULL);
4606     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4607     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4608     ok(delete_pf("msitest", FALSE), "File not installed\n");
4609
4610     SetCurrentDirectoryA(CURR_DIR);
4611
4612     DeleteFile(msifile);
4613     DeleteFile("msitest\\augustus");
4614     RemoveDirectory("msitest");
4615     RemoveDirectory("diffdir");
4616 }
4617
4618 static void set_admin_summary_info(const CHAR *name)
4619 {
4620     MSIHANDLE db, summary;
4621     UINT r;
4622
4623     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
4624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4625
4626     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
4627     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4628
4629     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
4630     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4631
4632     /* write the summary changes back to the stream */
4633     r = MsiSummaryInfoPersist(summary);
4634     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4635
4636     MsiCloseHandle(summary);
4637
4638     r = MsiDatabaseCommit(db);
4639     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4640
4641     MsiCloseHandle(db);
4642 }
4643
4644 static void test_admin(void)
4645 {
4646     UINT r;
4647
4648     CreateDirectoryA("msitest", NULL);
4649     create_file("msitest\\augustus", 500);
4650
4651     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
4652     set_admin_summary_info(msifile);
4653
4654     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4655
4656     r = MsiInstallProductA(msifile, NULL);
4657     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4658     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4659     ok(!delete_pf("msitest", FALSE), "File installed\n");
4660     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
4661     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
4662
4663     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
4664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4665     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4666     ok(!delete_pf("msitest", FALSE), "File installed\n");
4667     todo_wine
4668     {
4669         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
4670         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
4671     }
4672
4673     DeleteFile(msifile);
4674     DeleteFile("msitest\\augustus");
4675     RemoveDirectory("msitest");
4676 }
4677
4678 static void set_admin_property_stream(LPCSTR file)
4679 {
4680     IStorage *stg;
4681     IStream *stm;
4682     WCHAR fileW[MAX_PATH];
4683     HRESULT hr;
4684     DWORD count;
4685     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
4686
4687     /* AdminProperties */
4688     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
4689     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
4690         'M','y','P','r','o','p','=','4','2',0};
4691
4692     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
4693
4694     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
4695     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4696     if (!stg)
4697         return;
4698
4699     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4700     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4701
4702     hr = IStream_Write(stm, data, sizeof(data), &count);
4703     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4704
4705     IStream_Release(stm);
4706     IStorage_Release(stg);
4707 }
4708
4709 static void test_adminprops(void)
4710 {
4711     UINT r;
4712
4713     CreateDirectoryA("msitest", NULL);
4714     create_file("msitest\\augustus", 500);
4715
4716     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
4717     set_admin_summary_info(msifile);
4718     set_admin_property_stream(msifile);
4719
4720     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4721
4722     r = MsiInstallProductA(msifile, NULL);
4723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4724     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4725     ok(delete_pf("msitest", FALSE), "File installed\n");
4726
4727     DeleteFile(msifile);
4728     DeleteFile("msitest\\augustus");
4729     RemoveDirectory("msitest");
4730 }
4731
4732 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4733 {
4734     CHAR path[MAX_PATH];
4735
4736     lstrcpyA(path, PROG_FILES_DIR);
4737     lstrcatA(path, "\\");
4738     lstrcatA(path, file);
4739
4740     if (is_file)
4741         create_file_data(path, data, 500);
4742     else
4743         CreateDirectoryA(path, NULL);
4744 }
4745
4746 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4747
4748 static void test_removefiles(void)
4749 {
4750     UINT r;
4751
4752     CreateDirectoryA("msitest", NULL);
4753     create_file("msitest\\hydrogen", 500);
4754     create_file("msitest\\helium", 500);
4755     create_file("msitest\\lithium", 500);
4756
4757     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4758
4759     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4760
4761     r = MsiInstallProductA(msifile, NULL);
4762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4763     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4764     ok(!pf_exists("msitest\\helium"), "File installed\n");
4765     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4766     ok(pf_exists("msitest"), "File not installed\n");
4767
4768     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4769     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4770     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4771     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4772     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4773     ok(delete_pf("msitest", FALSE), "File deleted\n");
4774
4775     create_pf("msitest", FALSE);
4776     create_pf("msitest\\hydrogen", TRUE);
4777     create_pf("msitest\\helium", TRUE);
4778     create_pf("msitest\\lithium", TRUE);
4779
4780     r = MsiInstallProductA(msifile, NULL);
4781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4782     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4783     ok(pf_exists("msitest\\helium"), "File not installed\n");
4784     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4785     ok(pf_exists("msitest"), "File not installed\n");
4786
4787     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4788     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4789     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4790     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4791     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4792     ok(delete_pf("msitest", FALSE), "File deleted\n");
4793
4794     create_pf("msitest", FALSE);
4795     create_pf("msitest\\furlong", TRUE);
4796     create_pf("msitest\\firkin", TRUE);
4797     create_pf("msitest\\fortnight", TRUE);
4798     create_pf("msitest\\becquerel", TRUE);
4799     create_pf("msitest\\dioptre", TRUE);
4800     create_pf("msitest\\attoparsec", TRUE);
4801     create_pf("msitest\\storeys", TRUE);
4802     create_pf("msitest\\block", TRUE);
4803     create_pf("msitest\\siriometer", TRUE);
4804     create_pf("msitest\\cabout", FALSE);
4805     create_pf("msitest\\cabout\\blocker", TRUE);
4806
4807     r = MsiInstallProductA(msifile, NULL);
4808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4809     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4810     ok(!pf_exists("msitest\\helium"), "File installed\n");
4811     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4812     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4813     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4814     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4815     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4816     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4817     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4818     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4819     ok(!pf_exists("msitest\\block"), "File not deleted\n");
4820     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4821     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
4822     ok(pf_exists("msitest"), "File not installed\n");
4823
4824     create_pf("msitest\\furlong", TRUE);
4825     create_pf("msitest\\firkin", TRUE);
4826     create_pf("msitest\\fortnight", TRUE);
4827     create_pf("msitest\\storeys", TRUE);
4828     create_pf("msitest\\block", TRUE);
4829     create_pf("msitest\\siriometer", TRUE);
4830
4831     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4832     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4833     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4834     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4835     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4836     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4837     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4838     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4839     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4840     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4841     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4842     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4843     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4844     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4845     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4846     ok(pf_exists("msitest"), "Directory deleted\n");
4847
4848     r = MsiInstallProductA(msifile, NULL);
4849     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4850     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
4851     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
4852     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
4853     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4854     ok(pf_exists("msitest"), "Directory deleted\n");
4855
4856     delete_pf("msitest\\cabout\\blocker", TRUE);
4857
4858     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4859     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4860     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
4861     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4862
4863     DeleteFile(msifile);
4864     DeleteFile("msitest\\hydrogen");
4865     DeleteFile("msitest\\helium");
4866     DeleteFile("msitest\\lithium");
4867     RemoveDirectory("msitest");
4868 }
4869
4870 static void test_movefiles(void)
4871 {
4872     UINT r;
4873     char props[MAX_PATH];
4874
4875     CreateDirectoryA("msitest", NULL);
4876     create_file("msitest\\augustus", 100);
4877     create_file("cameroon", 100);
4878     create_file("djibouti", 100);
4879     create_file("egypt", 100);
4880     create_file("finland", 100);
4881     create_file("gambai", 100);
4882     create_file("honduras", 100);
4883     create_file("msitest\\india", 100);
4884     create_file("japan", 100);
4885     create_file("kenya", 100);
4886     CreateDirectoryA("latvia", NULL);
4887     create_file("nauru", 100);
4888     create_file("peru", 100);
4889     create_file("apple", 100);
4890     create_file("application", 100);
4891     create_file("ape", 100);
4892     create_file("foo", 100);
4893     create_file("fao", 100);
4894     create_file("fbod", 100);
4895     create_file("budding", 100);
4896     create_file("buddy", 100);
4897     create_file("bud", 100);
4898     create_file("bar", 100);
4899     create_file("bur", 100);
4900     create_file("bird", 100);
4901
4902     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4903
4904     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4905
4906     /* if the source or dest property is not a full path,
4907      * windows tries to access it as a network resource
4908      */
4909
4910     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4911             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4912             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4913
4914     r = MsiInstallProductA(msifile, props);
4915     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4916     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4917     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4918     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4919     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4920     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4921     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4922     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4923     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4924     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4925     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4926     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4927     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4928     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4929     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
4930     /* either apple or application will be moved depending on directory order */
4931     if (!delete_pf("msitest\\apple", TRUE))
4932         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4933     else
4934         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4935     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4936     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4937     /* either fao or foo will be moved depending on directory order */
4938     if (delete_pf("msitest\\foo", TRUE))
4939         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4940     else
4941         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4942     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4943     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4944     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4945     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4946     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4947     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4948     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4949     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4950     ok(delete_pf("msitest", FALSE), "File not installed\n");
4951     ok(DeleteFileA("cameroon"), "File moved\n");
4952     ok(!DeleteFileA("djibouti"), "File not moved\n");
4953     ok(DeleteFileA("egypt"), "File moved\n");
4954     ok(DeleteFileA("finland"), "File moved\n");
4955     ok(DeleteFileA("gambai"), "File moved\n");
4956     ok(!DeleteFileA("honduras"), "File not moved\n");
4957     ok(DeleteFileA("msitest\\india"), "File moved\n");
4958     ok(DeleteFileA("japan"), "File moved\n");
4959     ok(!DeleteFileA("kenya"), "File not moved\n");
4960     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4961     ok(!DeleteFileA("nauru"), "File not moved\n");
4962     ok(!DeleteFileA("peru"), "File not moved\n");
4963     ok(!DeleteFileA("apple"), "File not moved\n");
4964     ok(!DeleteFileA("application"), "File not moved\n");
4965     ok(DeleteFileA("ape"), "File moved\n");
4966     ok(!DeleteFileA("foo"), "File not moved\n");
4967     ok(!DeleteFileA("fao"), "File not moved\n");
4968     ok(DeleteFileA("fbod"), "File moved\n");
4969     ok(!DeleteFileA("budding"), "File not moved\n");
4970     ok(!DeleteFileA("buddy"), "File not moved\n");
4971     ok(DeleteFileA("bud"), "File moved\n");
4972     ok(!DeleteFileA("bar"), "File not moved\n");
4973     ok(!DeleteFileA("bur"), "File not moved\n");
4974     ok(DeleteFileA("bird"), "File moved\n");
4975
4976     DeleteFile("msitest\\augustus");
4977     RemoveDirectory("msitest");
4978     DeleteFile(msifile);
4979 }
4980
4981 static void test_missingcab(void)
4982 {
4983     UINT r;
4984
4985     CreateDirectoryA("msitest", NULL);
4986     create_file("msitest\\augustus", 500);
4987     create_file("maximus", 500);
4988
4989     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
4990
4991     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4992
4993     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4994
4995     create_pf("msitest", FALSE);
4996     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4997
4998     r = MsiInstallProductA(msifile, NULL);
4999     ok(r == ERROR_SUCCESS ||
5000        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
5001        "Expected ERROR_SUCCESS, got %u\n", r);
5002     if (r == ERROR_SUCCESS)
5003     {
5004       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5005       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5006     }
5007     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
5008     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
5009     ok(delete_pf("msitest", FALSE), "File not installed\n");
5010
5011     create_pf("msitest", FALSE);
5012     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
5013     create_pf("msitest\\gaius", TRUE);
5014
5015     r = MsiInstallProductA(msifile, "GAIUS=1");
5016     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5017     todo_wine
5018     {
5019         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
5020         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5021     }
5022     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
5023     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
5024     ok(delete_pf("msitest", FALSE), "File not installed\n");
5025
5026     DeleteFile("msitest\\augustus");
5027     RemoveDirectory("msitest");
5028     DeleteFile("maximus");
5029     DeleteFile("test1.cab");
5030     DeleteFile(msifile);
5031 }
5032
5033 static void test_duplicatefiles(void)
5034 {
5035     UINT r;
5036
5037     CreateDirectoryA("msitest", NULL);
5038     create_file("msitest\\maximus", 500);
5039     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
5040
5041     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5042
5043     /* fails if the destination folder is not a valid property */
5044
5045     r = MsiInstallProductA(msifile, NULL);
5046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5047     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5048     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
5049     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
5050     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
5051     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
5052     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
5053     ok(delete_pf("msitest", FALSE), "File not installed\n");
5054
5055     DeleteFile("msitest\\maximus");
5056     RemoveDirectory("msitest");
5057     DeleteFile(msifile);
5058 }
5059
5060 static void test_writeregistryvalues(void)
5061 {
5062     UINT r;
5063     LONG res;
5064     HKEY hkey;
5065     DWORD type, size;
5066     CHAR path[MAX_PATH];
5067
5068     CreateDirectoryA("msitest", NULL);
5069     create_file("msitest\\augustus", 500);
5070
5071     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
5072
5073     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5074
5075     r = MsiInstallProductA(msifile, NULL);
5076     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5077     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5078     ok(delete_pf("msitest", FALSE), "File installed\n");
5079
5080     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
5081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5082
5083     size = MAX_PATH;
5084     type = REG_MULTI_SZ;
5085     memset(path, 'a', MAX_PATH);
5086     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
5087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5088     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
5089     ok(size == 15, "Expected 15, got %d\n", size);
5090     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5091
5092     DeleteFile(msifile);
5093     DeleteFile("msitest\\augustus");
5094     RemoveDirectory("msitest");
5095
5096     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
5097     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
5098 }
5099
5100 static void test_sourcefolder(void)
5101 {
5102     UINT r;
5103
5104     CreateDirectoryA("msitest", NULL);
5105     create_file("augustus", 500);
5106
5107     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
5108
5109     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5110
5111     r = MsiInstallProductA(msifile, NULL);
5112     ok(r == ERROR_INSTALL_FAILURE,
5113        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5114     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5115     todo_wine
5116     {
5117         ok(!delete_pf("msitest", FALSE), "File installed\n");
5118     }
5119
5120     RemoveDirectoryA("msitest");
5121
5122     r = MsiInstallProductA(msifile, NULL);
5123     ok(r == ERROR_INSTALL_FAILURE,
5124        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5125     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5126     todo_wine
5127     {
5128         ok(!delete_pf("msitest", FALSE), "File installed\n");
5129     }
5130
5131     DeleteFile(msifile);
5132     DeleteFile("augustus");
5133 }
5134
5135 static void test_customaction51(void)
5136 {
5137     UINT r;
5138
5139     CreateDirectoryA("msitest", NULL);
5140     create_file("msitest\\augustus", 500);
5141
5142     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
5143
5144     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5145
5146     r = MsiInstallProductA(msifile, NULL);
5147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5148     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5149     ok(delete_pf("msitest", FALSE), "File installed\n");
5150
5151     DeleteFile(msifile);
5152     DeleteFile("msitest\\augustus");
5153     RemoveDirectory("msitest");
5154 }
5155
5156 static void test_installstate(void)
5157 {
5158     UINT r;
5159
5160     CreateDirectoryA("msitest", NULL);
5161     create_file("msitest\\alpha", 500);
5162     create_file("msitest\\beta", 500);
5163     create_file("msitest\\gamma", 500);
5164     create_file("msitest\\theta", 500);
5165     create_file("msitest\\delta", 500);
5166     create_file("msitest\\epsilon", 500);
5167     create_file("msitest\\zeta", 500);
5168     create_file("msitest\\iota", 500);
5169     create_file("msitest\\eta", 500);
5170     create_file("msitest\\kappa", 500);
5171     create_file("msitest\\lambda", 500);
5172     create_file("msitest\\mu", 500);
5173
5174     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
5175
5176     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5177
5178     r = MsiInstallProductA(msifile, NULL);
5179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5180     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5181     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5182     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
5183     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5184     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5185     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5186     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
5187     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5188     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5189     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5190     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5191     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5192     ok(delete_pf("msitest", FALSE), "File not installed\n");
5193
5194     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
5195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5196     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5197     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5198     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
5199     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5200     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5201     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
5202     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
5203     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5204     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
5205     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5206     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5207     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5208     ok(delete_pf("msitest", FALSE), "File not installed\n");
5209
5210     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
5211     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5212     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5213     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5214     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
5215     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5216     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5217     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5218     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
5219     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5220     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5221     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5222     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5223     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5224     ok(delete_pf("msitest", FALSE), "File not installed\n");
5225
5226     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
5227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5228     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
5229     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5230     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
5231     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
5232     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5233     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5234     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
5235     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5236     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5237     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5238     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5239     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5240     ok(!delete_pf("msitest", FALSE), "File installed\n");
5241
5242     DeleteFile(msifile);
5243     DeleteFile("msitest\\alpha");
5244     DeleteFile("msitest\\beta");
5245     DeleteFile("msitest\\gamma");
5246     DeleteFile("msitest\\theta");
5247     DeleteFile("msitest\\delta");
5248     DeleteFile("msitest\\epsilon");
5249     DeleteFile("msitest\\zeta");
5250     DeleteFile("msitest\\iota");
5251     DeleteFile("msitest\\eta");
5252     DeleteFile("msitest\\kappa");
5253     DeleteFile("msitest\\lambda");
5254     DeleteFile("msitest\\mu");
5255     RemoveDirectory("msitest");
5256 }
5257
5258 struct sourcepathmap
5259 {
5260     BOOL sost; /* shortone\shorttwo */
5261     BOOL solt; /* shortone\longtwo */
5262     BOOL lost; /* longone\shorttwo */
5263     BOOL lolt; /* longone\longtwo */
5264     BOOL soste; /* shortone\shorttwo source exists */
5265     BOOL solte; /* shortone\longtwo source exists */
5266     BOOL loste; /* longone\shorttwo source exists */
5267     BOOL lolte; /* longone\longtwo source exists */
5268     UINT err;
5269     DWORD size;
5270 } spmap[256] =
5271 {
5272     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5273     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5274     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5275     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5276     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5277     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5278     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5279     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5280     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5281     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5282     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5283     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5284     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5285     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5286     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5287     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5288     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5289     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5290     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5291     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5292     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5293     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5294     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5295     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5296     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5297     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5298     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5299     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5300     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5301     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5302     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5303     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5304     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5305     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5306     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5307     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5308     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5309     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5310     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5311     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5312     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5313     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5314     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5315     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5316     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5317     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5318     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5319     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5320     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5321     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5322     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5323     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5324     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5325     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5326     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5327     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5328     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5329     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5330     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5331     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5332     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5333     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5334     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5335     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5336     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5337     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5338     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5339     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5340     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5341     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5342     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5343     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5344     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5345     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5346     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5347     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5348     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5349     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5350     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5351     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5352     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5353     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5354     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5355     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5356     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5357     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5358     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5359     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5360     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5361     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5362     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5363     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5364     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5365     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5366     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5367     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5368     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5369     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5370     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5371     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5372     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5373     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5374     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5375     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5376     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5377     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5378     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5379     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5380     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5381     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5382     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5383     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5384     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5385     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5386     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5387     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5388     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5389     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5390     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5391     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5392     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5393     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5394     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5395     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5396     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5397     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5398     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5399     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5400     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5401     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5402     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5403     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5404     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5405     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5406     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5407     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5408     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5409     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5410     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5411     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5412     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5413     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5414     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5415     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5416     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5417     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5418     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5419     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5420     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5421     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5422     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5423     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5424     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5425     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5426     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5427     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5428     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5429     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5430     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5431     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5432     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5433     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5434     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5435     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5436     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5437     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5438     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5439     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5440     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5441     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5442     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5443     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5444     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5445     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5446     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5447     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5448     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5449     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5450     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5451     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5452     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5453     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5454     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5455     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5456     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5457     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5458     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5459     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5460     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5461     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5462     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5463     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5464     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5465     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5466     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5467     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5468     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5469     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5470     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5471     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5472     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5473     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5474     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5475     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5476     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5477     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5478     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5479     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5480     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5481     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5482     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5483     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5484     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5485     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5486     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5487     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5488     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5489     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5490     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5491     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5492     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5493     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5494     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5495     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5496     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5497     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5498     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5499     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5500     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5501     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5502     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5503     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5504     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5505     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5506     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5507     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5508     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5509     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5510     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5511     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5512     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5513     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5514     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5515     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5516     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5517     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5518     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5519     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5520     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5521     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5522     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5523     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5524     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5525     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5526     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5527     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5528 };
5529
5530 static DWORD get_pf_file_size(LPCSTR file)
5531 {
5532     CHAR path[MAX_PATH];
5533     HANDLE hfile;
5534     DWORD size;
5535
5536     lstrcpyA(path, PROG_FILES_DIR);
5537     lstrcatA(path, "\\");
5538     lstrcatA(path, file);
5539
5540     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
5541     if (hfile == INVALID_HANDLE_VALUE)
5542         return 0;
5543
5544     size = GetFileSize(hfile, NULL);
5545     CloseHandle(hfile);
5546     return size;
5547 }
5548
5549 static void test_sourcepath(void)
5550 {
5551     UINT r, i;
5552
5553     if (!winetest_interactive)
5554     {
5555         skip("Run in interactive mode to run source path tests.\n");
5556         return;
5557     }
5558
5559     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
5560
5561     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5562
5563     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
5564     {
5565         if (spmap[i].sost)
5566         {
5567             CreateDirectoryA("shortone", NULL);
5568             CreateDirectoryA("shortone\\shorttwo", NULL);
5569         }
5570
5571         if (spmap[i].solt)
5572         {
5573             CreateDirectoryA("shortone", NULL);
5574             CreateDirectoryA("shortone\\longtwo", NULL);
5575         }
5576
5577         if (spmap[i].lost)
5578         {
5579             CreateDirectoryA("longone", NULL);
5580             CreateDirectoryA("longone\\shorttwo", NULL);
5581         }
5582
5583         if (spmap[i].lolt)
5584         {
5585             CreateDirectoryA("longone", NULL);
5586             CreateDirectoryA("longone\\longtwo", NULL);
5587         }
5588
5589         if (spmap[i].soste)
5590             create_file("shortone\\shorttwo\\augustus", 50);
5591         if (spmap[i].solte)
5592             create_file("shortone\\longtwo\\augustus", 100);
5593         if (spmap[i].loste)
5594             create_file("longone\\shorttwo\\augustus", 150);
5595         if (spmap[i].lolte)
5596             create_file("longone\\longtwo\\augustus", 200);
5597
5598         r = MsiInstallProductA(msifile, NULL);
5599         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
5600         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
5601            "%d: Expected %d, got %d\n", i, spmap[i].size,
5602            get_pf_file_size("msitest\\augustus"));
5603
5604         if (r == ERROR_SUCCESS)
5605         {
5606             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
5607             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
5608         }
5609         else
5610         {
5611             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
5612             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
5613         }
5614
5615         DeleteFileA("shortone\\shorttwo\\augustus");
5616         DeleteFileA("shortone\\longtwo\\augustus");
5617         DeleteFileA("longone\\shorttwo\\augustus");
5618         DeleteFileA("longone\\longtwo\\augustus");
5619         RemoveDirectoryA("shortone\\shorttwo");
5620         RemoveDirectoryA("shortone\\longtwo");
5621         RemoveDirectoryA("longone\\shorttwo");
5622         RemoveDirectoryA("longone\\longtwo");
5623         RemoveDirectoryA("shortone");
5624         RemoveDirectoryA("longone");
5625     }
5626
5627     DeleteFileA(msifile);
5628 }
5629
5630 static void test_MsiConfigureProductEx(void)
5631 {
5632     UINT r;
5633     LONG res;
5634     DWORD type, size;
5635     HKEY props, source;
5636     CHAR keypath[MAX_PATH * 2];
5637     CHAR localpack[MAX_PATH];
5638
5639     if (on_win9x)
5640     {
5641         win_skip("Different registry keys on Win9x and WinMe\n");
5642         return;
5643     }
5644
5645     CreateDirectoryA("msitest", NULL);
5646     create_file("msitest\\hydrogen", 500);
5647     create_file("msitest\\helium", 500);
5648     create_file("msitest\\lithium", 500);
5649
5650     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5651
5652     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5653
5654     /* NULL szProduct */
5655     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
5656                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5657     ok(r == ERROR_INVALID_PARAMETER,
5658        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5659
5660     /* empty szProduct */
5661     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
5662                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5663     ok(r == ERROR_INVALID_PARAMETER,
5664        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5665
5666     /* garbage szProduct */
5667     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
5668                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5669     ok(r == ERROR_INVALID_PARAMETER,
5670        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5671
5672     /* guid without brackets */
5673     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
5674                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5675                                "PROPVAR=42");
5676     ok(r == ERROR_INVALID_PARAMETER,
5677        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5678
5679     /* guid with brackets */
5680     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
5681                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5682                                "PROPVAR=42");
5683     ok(r == ERROR_UNKNOWN_PRODUCT,
5684        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5685
5686     /* same length as guid, but random */
5687     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
5688                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5689                                "PROPVAR=42");
5690     ok(r == ERROR_UNKNOWN_PRODUCT,
5691        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5692
5693     /* product not installed yet */
5694     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5695                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5696                                "PROPVAR=42");
5697     ok(r == ERROR_UNKNOWN_PRODUCT,
5698        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5699
5700     /* install the product, per-user unmanaged */
5701     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
5702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5703     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5704     ok(pf_exists("msitest\\helium"), "File not installed\n");
5705     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5706     ok(pf_exists("msitest"), "File not installed\n");
5707
5708     /* product is installed per-user managed, remove it */
5709     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5710                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5711                                "PROPVAR=42");
5712     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5713     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5714     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5715     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5716     todo_wine
5717     {
5718         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5719     }
5720
5721     /* product has been removed */
5722     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5723                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5724                                "PROPVAR=42");
5725     ok(r == ERROR_UNKNOWN_PRODUCT,
5726        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
5727
5728     /* install the product, machine */
5729     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5730     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5731     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5732     ok(pf_exists("msitest\\helium"), "File not installed\n");
5733     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5734     ok(pf_exists("msitest"), "File not installed\n");
5735
5736     /* product is installed machine, remove it */
5737     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5738                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5739                                "PROPVAR=42");
5740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5741     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5742     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5743     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5744     todo_wine
5745     {
5746         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5747     }
5748
5749     /* product has been removed */
5750     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5751                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5752                                "PROPVAR=42");
5753     ok(r == ERROR_UNKNOWN_PRODUCT,
5754        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
5755
5756     /* install the product, machine */
5757     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5759     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5760     ok(pf_exists("msitest\\helium"), "File not installed\n");
5761     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5762     ok(pf_exists("msitest"), "File not installed\n");
5763
5764     DeleteFileA(msifile);
5765
5766     /* local msifile is removed */
5767     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5768                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5769                                "PROPVAR=42");
5770     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5771     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5772     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5773     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5774     todo_wine
5775     {
5776         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5777     }
5778
5779     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5780
5781     /* install the product, machine */
5782     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5783     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5784     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5785     ok(pf_exists("msitest\\helium"), "File not installed\n");
5786     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5787     ok(pf_exists("msitest"), "File not installed\n");
5788
5789     DeleteFileA(msifile);
5790
5791     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
5792     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
5793     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
5794
5795     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5797
5798     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
5799                          (const BYTE *)"C:\\idontexist.msi", 18);
5800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5801
5802     /* LocalPackage is used to find the cached msi package */
5803     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5804                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5805                                "PROPVAR=42");
5806     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
5807        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
5808     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5809     ok(pf_exists("msitest\\helium"), "File not installed\n");
5810     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5811     ok(pf_exists("msitest"), "File not installed\n");
5812
5813     RegCloseKey(props);
5814     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5815
5816     /* LastUsedSource (local msi package) can be used as a last resort */
5817     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5818                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5819                                "PROPVAR=42");
5820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5821     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5822     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5823     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5824     todo_wine
5825     {
5826         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5827     }
5828
5829     /* install the product, machine */
5830     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5832     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5833     ok(pf_exists("msitest\\helium"), "File not installed\n");
5834     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5835     ok(pf_exists("msitest"), "File not installed\n");
5836
5837     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
5838     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
5839     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
5840
5841     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5842     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5843
5844     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
5845                          (const BYTE *)"C:\\idontexist.msi", 18);
5846     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5847
5848     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
5849     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
5850
5851     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
5852     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5853
5854     type = REG_SZ;
5855     size = MAX_PATH;
5856     res = RegQueryValueExA(source, "PackageName", NULL, &type,
5857                            (LPBYTE)localpack, &size);
5858     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5859
5860     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
5861                          (const BYTE *)"idontexist.msi", 15);
5862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5863
5864     /* SourceList is altered */
5865     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5866                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5867                                "PROPVAR=42");
5868     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
5869        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
5870     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5871     ok(pf_exists("msitest\\helium"), "File not installed\n");
5872     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5873     ok(pf_exists("msitest"), "File not installed\n");
5874
5875     /* restore the SourceList */
5876     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
5877                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
5878     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5879
5880     /* finally remove the product */
5881     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5882                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5883                                "PROPVAR=42");
5884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5885     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5886     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5887     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5888     todo_wine
5889     {
5890         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5891     }
5892
5893     DeleteFileA(msifile);
5894     RegCloseKey(source);
5895     RegCloseKey(props);
5896     DeleteFileA("msitest\\hydrogen");
5897     DeleteFileA("msitest\\helium");
5898     DeleteFileA("msitest\\lithium");
5899     RemoveDirectoryA("msitest");
5900 }
5901
5902 static void test_missingcomponent(void)
5903 {
5904     UINT r;
5905
5906     CreateDirectoryA("msitest", NULL);
5907     create_file("msitest\\hydrogen", 500);
5908     create_file("msitest\\helium", 500);
5909     create_file("msitest\\lithium", 500);
5910     create_file("beryllium", 500);
5911
5912     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
5913
5914     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5915
5916     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
5917     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5918     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5919     ok(pf_exists("msitest\\helium"), "File not installed\n");
5920     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5921     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5922     ok(pf_exists("msitest"), "File not installed\n");
5923
5924     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
5925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5926     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5927     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5928     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5929     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5930     todo_wine
5931     {
5932         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5933     }
5934
5935     DeleteFileA(msifile);
5936     DeleteFileA("msitest\\hydrogen");
5937     DeleteFileA("msitest\\helium");
5938     DeleteFileA("msitest\\lithium");
5939     DeleteFileA("beryllium");
5940     RemoveDirectoryA("msitest");
5941 }
5942
5943 static void test_sourcedirprop(void)
5944 {
5945     UINT r;
5946     CHAR props[MAX_PATH];
5947
5948     CreateDirectoryA("msitest", NULL);
5949     create_file("msitest\\augustus", 500);
5950
5951     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
5952
5953     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5954
5955     r = MsiInstallProductA(msifile, NULL);
5956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5957     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5958     ok(delete_pf("msitest", FALSE), "File installed\n");
5959
5960     DeleteFile("msitest\\augustus");
5961     RemoveDirectory("msitest");
5962
5963     CreateDirectoryA("altsource", NULL);
5964     CreateDirectoryA("altsource\\msitest", NULL);
5965     create_file("altsource\\msitest\\augustus", 500);
5966
5967     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
5968
5969     r = MsiInstallProductA(msifile, props);
5970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5971     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5972     ok(delete_pf("msitest", FALSE), "File installed\n");
5973
5974     DeleteFile(msifile);
5975     DeleteFile("altsource\\msitest\\augustus");
5976     RemoveDirectory("altsource\\msitest");
5977     RemoveDirectory("altsource");
5978 }
5979
5980 static void test_adminimage(void)
5981 {
5982     UINT r;
5983
5984     CreateDirectoryA("msitest", NULL);
5985     CreateDirectoryA("msitest\\first", NULL);
5986     CreateDirectoryA("msitest\\second", NULL);
5987     CreateDirectoryA("msitest\\cabout", NULL);
5988     CreateDirectoryA("msitest\\cabout\\new", NULL);
5989     create_file("msitest\\one.txt", 100);
5990     create_file("msitest\\first\\two.txt", 100);
5991     create_file("msitest\\second\\three.txt", 100);
5992     create_file("msitest\\cabout\\four.txt", 100);
5993     create_file("msitest\\cabout\\new\\five.txt", 100);
5994     create_file("msitest\\filename", 100);
5995     create_file("msitest\\service.exe", 100);
5996
5997     create_database_wordcount(msifile, ai_tables,
5998                               sizeof(ai_tables) / sizeof(msi_table),
5999                               msidbSumInfoSourceTypeAdminImage);
6000
6001     r = MsiInstallProductA(msifile, NULL);
6002     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6003
6004     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6005     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6006     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6007     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6008     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6009     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6010     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6011     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6012     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
6013     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6014     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6015     ok(delete_pf("msitest", FALSE), "File not installed\n");
6016
6017     DeleteFileA("msitest.msi");
6018     DeleteFileA("msitest\\cabout\\new\\five.txt");
6019     DeleteFileA("msitest\\cabout\\four.txt");
6020     DeleteFileA("msitest\\second\\three.txt");
6021     DeleteFileA("msitest\\first\\two.txt");
6022     DeleteFileA("msitest\\one.txt");
6023     DeleteFileA("msitest\\service.exe");
6024     DeleteFileA("msitest\\filename");
6025     RemoveDirectoryA("msitest\\cabout\\new");
6026     RemoveDirectoryA("msitest\\cabout");
6027     RemoveDirectoryA("msitest\\second");
6028     RemoveDirectoryA("msitest\\first");
6029     RemoveDirectoryA("msitest");
6030 }
6031
6032 static void test_propcase(void)
6033 {
6034     UINT r;
6035
6036     CreateDirectoryA("msitest", NULL);
6037     create_file("msitest\\augustus", 500);
6038
6039     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
6040
6041     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6042
6043     r = MsiInstallProductA(msifile, "MyProp=42");
6044     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6045     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6046     ok(delete_pf("msitest", FALSE), "File not installed\n");
6047
6048     DeleteFile(msifile);
6049     DeleteFile("msitest\\augustus");
6050     RemoveDirectory("msitest");
6051 }
6052
6053 static void test_int_widths( void )
6054 {
6055     static const char int0[] = "int0\ni0\nint0\tint0\n1";
6056     static const char int1[] = "int1\ni1\nint1\tint1\n1";
6057     static const char int2[] = "int2\ni2\nint2\tint2\n1";
6058     static const char int3[] = "int3\ni3\nint3\tint3\n1";
6059     static const char int4[] = "int4\ni4\nint4\tint4\n1";
6060     static const char int5[] = "int5\ni5\nint5\tint5\n1";
6061     static const char int8[] = "int8\ni8\nint8\tint8\n1";
6062
6063     static const struct
6064     {
6065         const char  *data;
6066         unsigned int size;
6067         UINT         ret;
6068     }
6069     tests[] =
6070     {
6071         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
6072         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
6073         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
6074         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
6075         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
6076         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
6077         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
6078     };
6079
6080     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
6081     MSIHANDLE db;
6082     UINT r, i;
6083
6084     GetTempPathA(MAX_PATH, tmpdir);
6085     CreateDirectoryA(tmpdir, NULL);
6086
6087     strcpy(msitable, tmpdir);
6088     strcat(msitable, "\\msitable.idt");
6089
6090     strcpy(msidb, tmpdir);
6091     strcat(msidb, "\\msitest.msi");
6092
6093     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
6094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6095
6096     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
6097     {
6098         write_file(msitable, tests[i].data, tests[i].size);
6099
6100         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
6101         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
6102
6103         r = MsiDatabaseCommit(db);
6104         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6105         DeleteFileA(msitable);
6106     }
6107
6108     MsiCloseHandle(db);
6109     DeleteFileA(msidb);
6110     RemoveDirectoryA(tmpdir);
6111 }
6112
6113 START_TEST(install)
6114 {
6115     DWORD len;
6116     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
6117     STATEMGRSTATUS status;
6118     BOOL ret = FALSE;
6119
6120     init_functionpointers();
6121
6122     on_win9x = check_win9x();
6123
6124     GetCurrentDirectoryA(MAX_PATH, prev_path);
6125     GetTempPath(MAX_PATH, temp_path);
6126     SetCurrentDirectoryA(temp_path);
6127
6128     lstrcpyA(CURR_DIR, temp_path);
6129     len = lstrlenA(CURR_DIR);
6130
6131     if(len && (CURR_DIR[len - 1] == '\\'))
6132         CURR_DIR[len - 1] = 0;
6133
6134     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
6135
6136     /* Create a restore point ourselves so we circumvent the multitude of restore points
6137      * that would have been created by all the installation and removal tests.
6138      */
6139     if (pSRSetRestorePointA)
6140     {
6141         memset(&status, 0, sizeof(status));
6142         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
6143     }
6144
6145     /* Create only one log file and don't append. We have to pass something
6146      * for the log mode for this to work. The logfile needs to have an absolute
6147      * path otherwise we still end up with some extra logfiles as some tests
6148      * change the current directory.
6149      */
6150     lstrcpyA(log_file, temp_path);
6151     lstrcatA(log_file, "\\msitest.log");
6152     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
6153
6154     test_MsiInstallProduct();
6155     test_MsiSetComponentState();
6156     test_packagecoltypes();
6157     test_continuouscabs();
6158     test_caborder();
6159     test_mixedmedia();
6160     test_samesequence();
6161     test_uiLevelFlags();
6162     test_readonlyfile();
6163     test_setdirproperty();
6164     test_cabisextracted();
6165     test_concurrentinstall();
6166     test_setpropertyfolder();
6167     test_publish_registerproduct();
6168     test_publish_publishproduct();
6169     test_publish_publishfeatures();
6170     test_publish_registeruser();
6171     test_publish_processcomponents();
6172     test_publish();
6173     test_publishsourcelist();
6174     test_transformprop();
6175     test_currentworkingdir();
6176     test_admin();
6177     test_adminprops();
6178     test_removefiles();
6179     test_movefiles();
6180     test_missingcab();
6181     test_duplicatefiles();
6182     test_writeregistryvalues();
6183     test_sourcefolder();
6184     test_customaction51();
6185     test_installstate();
6186     test_sourcepath();
6187     test_MsiConfigureProductEx();
6188     test_missingcomponent();
6189     test_sourcedirprop();
6190     test_adminimage();
6191     test_propcase();
6192     test_int_widths();
6193
6194     DeleteFileA(log_file);
6195
6196     if (pSRSetRestorePointA && ret)
6197     {
6198         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
6199         if (ret)
6200             remove_restore_point(status.llSequenceNumber);
6201     }
6202     FreeLibrary(hsrclient);
6203
6204     SetCurrentDirectoryA(prev_path);
6205 }