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