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