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