msi/tests: Fix explicit C:\\Program Files\\ references.
[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", strlen("readonlyfile"), &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     CHAR program_files_maximus[MAX_PATH];
3072
3073     static const CHAR keyfmt[] =
3074         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3075         "UserData\\%s\\Components\\%s";
3076     static const CHAR compkey[] =
3077         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
3078
3079     get_user_sid(&usersid);
3080     if (!usersid)
3081     {
3082         skip("ConvertSidToStringSidA is not available\n");
3083         return;
3084     }
3085
3086     CreateDirectoryA("msitest", NULL);
3087     create_file("msitest\\maximus", 500);
3088
3089     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
3090
3091     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3092
3093     /* ProcessComponents, per-user */
3094     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3096     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3097     ok(delete_pf("msitest", FALSE), "File not installed\n");
3098
3099     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
3100
3101     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
3102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3103
3104     size = MAX_PATH;
3105     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3106                            NULL, NULL, (LPBYTE)val, &size);
3107     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3108
3109     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
3110     lstrcatA(program_files_maximus,"\\msitest\\maximus");
3111
3112     ok(!lstrcmpA(val, program_files_maximus),
3113        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3114
3115     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
3116     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3117
3118     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3119     RegDeleteKeyA(comp, "");
3120     RegCloseKey(comp);
3121
3122     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
3123
3124     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
3125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3126
3127     size = MAX_PATH;
3128     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3129                            NULL, NULL, (LPBYTE)val, &size);
3130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3131     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3132        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3133
3134     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
3135     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3136
3137     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3138     RegDeleteKeyA(comp, "");
3139     RegCloseKey(comp);
3140
3141     /* ProcessComponents, machine */
3142     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
3143     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3144     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3145     ok(delete_pf("msitest", FALSE), "File not installed\n");
3146
3147     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
3148
3149     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
3150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3151
3152     size = MAX_PATH;
3153     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3154                            NULL, NULL, (LPBYTE)val, &size);
3155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3156     ok(!lstrcmpA(val, program_files_maximus),
3157        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3158
3159     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
3160     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3161
3162     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3163     RegDeleteKeyA(comp, "");
3164     RegCloseKey(comp);
3165
3166     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
3167
3168     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
3169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3170
3171     size = MAX_PATH;
3172     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3173                            NULL, NULL, (LPBYTE)val, &size);
3174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3175     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3176        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3177
3178     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
3179     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3180
3181     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3182     RegDeleteKeyA(comp, "");
3183     RegCloseKey(comp);
3184
3185     DeleteFile(msifile);
3186     DeleteFile("msitest\\maximus");
3187     RemoveDirectory("msitest");
3188 }
3189
3190 static void test_publish(void)
3191 {
3192     UINT r;
3193     LONG res;
3194     HKEY uninstall, prodkey;
3195     INSTALLSTATE state;
3196     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3197     char date[MAX_PATH];
3198     char temp[MAX_PATH];
3199
3200     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3201
3202     if (!pMsiQueryComponentStateA)
3203     {
3204         skip("MsiQueryComponentStateA is not available\n");
3205         return;
3206     }
3207
3208     get_date_str(date);
3209     GetTempPath(MAX_PATH, temp);
3210
3211     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
3212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3213
3214     CreateDirectoryA("msitest", NULL);
3215     create_file("msitest\\maximus", 500);
3216
3217     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3218
3219     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3220
3221     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3222     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3223
3224     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3225     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3226
3227     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3228     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3229
3230     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3231                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3232     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3233     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3234
3235     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3236     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3237
3238     /* nothing published */
3239     r = MsiInstallProductA(msifile, NULL);
3240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3241     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3242     ok(pf_exists("msitest"), "File not installed\n");
3243
3244     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3245     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3246
3247     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3248     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3249
3250     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3251     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3252
3253     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3254                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3255     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3256     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3257
3258     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3259     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3260
3261     /* PublishProduct and RegisterProduct */
3262     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
3263     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3264     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3265     ok(pf_exists("msitest"), "File not installed\n");
3266
3267     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3268     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3269
3270     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3271     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3272
3273     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3274     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3275
3276     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3277                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3278     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3279     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3280
3281     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3283
3284     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3285     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3286     CHECK_REG_STR(prodkey, "InstallDate", date);
3287     CHECK_REG_STR(prodkey, "InstallSource", temp);
3288     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3289     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3290     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3291     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3292     CHECK_REG_STR(prodkey, "Comments", NULL);
3293     CHECK_REG_STR(prodkey, "Contact", NULL);
3294     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3295     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3296     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3297     CHECK_REG_STR(prodkey, "Readme", NULL);
3298     CHECK_REG_STR(prodkey, "Size", NULL);
3299     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3300     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3301     CHECK_REG_DWORD(prodkey, "Language", 1033);
3302     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3303     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3304     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3305     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3306     todo_wine
3307     {
3308         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3309     }
3310
3311     RegCloseKey(prodkey);
3312
3313     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3315     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3316     ok(pf_exists("msitest"), "File deleted\n");
3317
3318     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3319     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3320
3321     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3322     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3323
3324     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3325     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3326
3327     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3328                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3329     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3330     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3331
3332     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3333     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3334
3335     /* complete install */
3336     r = MsiInstallProductA(msifile, "FULL=1");
3337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3339     ok(pf_exists("msitest"), "File not installed\n");
3340
3341     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3342     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3343
3344     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3345     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3346
3347     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3348     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3349
3350     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3351                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3352     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3353     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3354
3355     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3357
3358     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3359     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3360     CHECK_REG_STR(prodkey, "InstallDate", date);
3361     CHECK_REG_STR(prodkey, "InstallSource", temp);
3362     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3363     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3364     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3365     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3366     CHECK_REG_STR(prodkey, "Comments", NULL);
3367     CHECK_REG_STR(prodkey, "Contact", NULL);
3368     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3369     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3370     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3371     CHECK_REG_STR(prodkey, "Readme", NULL);
3372     CHECK_REG_STR(prodkey, "Size", NULL);
3373     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3374     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3375     CHECK_REG_DWORD(prodkey, "Language", 1033);
3376     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3377     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3378     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3379     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3380     todo_wine
3381     {
3382         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3383     }
3384
3385     RegCloseKey(prodkey);
3386
3387     /* no UnpublishFeatures */
3388     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3390     ok(!pf_exists("msitest\\maximus"), "File deleted\n");
3391     todo_wine
3392     {
3393         ok(!pf_exists("msitest"), "File deleted\n");
3394     }
3395
3396     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3397     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3398
3399     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3400     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3401
3402     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3403     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3404
3405     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3406                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3407     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3408     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3409
3410     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3411     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3412
3413     /* complete install */
3414     r = MsiInstallProductA(msifile, "FULL=1");
3415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3416     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3417     ok(pf_exists("msitest"), "File not installed\n");
3418
3419     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3420     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3421
3422     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3423     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3424
3425     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3426     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3427
3428     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3429                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3431     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3432
3433     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3437     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3438     CHECK_REG_STR(prodkey, "InstallDate", date);
3439     CHECK_REG_STR(prodkey, "InstallSource", temp);
3440     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3441     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3442     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3443     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3444     CHECK_REG_STR(prodkey, "Comments", NULL);
3445     CHECK_REG_STR(prodkey, "Contact", NULL);
3446     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3447     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3448     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3449     CHECK_REG_STR(prodkey, "Readme", NULL);
3450     CHECK_REG_STR(prodkey, "Size", NULL);
3451     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3452     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3453     CHECK_REG_DWORD(prodkey, "Language", 1033);
3454     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3455     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3456     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3457     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3458     todo_wine
3459     {
3460         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3461     }
3462
3463     RegCloseKey(prodkey);
3464
3465     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
3466     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
3467     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3468     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
3469     ok(pf_exists("msitest"), "File deleted\n");
3470
3471     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3472     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3473
3474     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3475     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3476
3477     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3478     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3479
3480     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3481                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3483     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3484
3485     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3487
3488     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3489     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3490     CHECK_REG_STR(prodkey, "InstallDate", date);
3491     CHECK_REG_STR(prodkey, "InstallSource", temp);
3492     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3493     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3494     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3495     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3496     CHECK_REG_STR(prodkey, "Comments", NULL);
3497     CHECK_REG_STR(prodkey, "Contact", NULL);
3498     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3499     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3500     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3501     CHECK_REG_STR(prodkey, "Readme", NULL);
3502     CHECK_REG_STR(prodkey, "Size", NULL);
3503     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3504     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3505     CHECK_REG_DWORD(prodkey, "Language", 1033);
3506     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3507     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3508     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3509     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3510     todo_wine
3511     {
3512         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3513     }
3514
3515     RegCloseKey(prodkey);
3516
3517     /* complete install */
3518     r = MsiInstallProductA(msifile, "FULL=1");
3519     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3520     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3521     ok(pf_exists("msitest"), "File not installed\n");
3522
3523     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3524     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3525
3526     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3527     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3528
3529     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3530     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3531
3532     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3533                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3534     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3535     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3536
3537     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3539
3540     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3541     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3542     CHECK_REG_STR(prodkey, "InstallDate", date);
3543     CHECK_REG_STR(prodkey, "InstallSource", temp);
3544     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3545     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3546     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3547     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3548     CHECK_REG_STR(prodkey, "Comments", NULL);
3549     CHECK_REG_STR(prodkey, "Contact", NULL);
3550     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3551     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3552     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3553     CHECK_REG_STR(prodkey, "Readme", NULL);
3554     CHECK_REG_STR(prodkey, "Size", NULL);
3555     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3556     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3557     CHECK_REG_DWORD(prodkey, "Language", 1033);
3558     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3559     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3560     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3561     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3562     todo_wine
3563     {
3564         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3565     }
3566
3567     RegCloseKey(prodkey);
3568
3569     /* UnpublishFeatures, both features removed */
3570     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
3571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3572     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3573     todo_wine
3574     {
3575         ok(!pf_exists("msitest"), "File not deleted\n");
3576     }
3577
3578     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3579     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3580
3581     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3582     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3583
3584     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3585     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3586
3587     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3588                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3589     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3590     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3591
3592     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3593     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3594
3595     /* complete install */
3596     r = MsiInstallProductA(msifile, "FULL=1");
3597     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3598     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3599     ok(pf_exists("msitest"), "File not installed\n");
3600
3601     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3602     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3603
3604     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3605     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3606
3607     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3608     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3609
3610     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3611                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3612     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3613     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3614
3615     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3616     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3617
3618     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3619     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3620     CHECK_REG_STR(prodkey, "InstallDate", date);
3621     CHECK_REG_STR(prodkey, "InstallSource", temp);
3622     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3623     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3624     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3625     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3626     CHECK_REG_STR(prodkey, "Comments", NULL);
3627     CHECK_REG_STR(prodkey, "Contact", NULL);
3628     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3629     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3630     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3631     CHECK_REG_STR(prodkey, "Readme", NULL);
3632     CHECK_REG_STR(prodkey, "Size", NULL);
3633     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3634     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3635     CHECK_REG_DWORD(prodkey, "Language", 1033);
3636     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3637     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3638     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3639     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3640     todo_wine
3641     {
3642         CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3643     }
3644
3645     RegCloseKey(prodkey);
3646
3647     /* complete uninstall */
3648     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3649     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3650     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3651     todo_wine
3652     {
3653         ok(!pf_exists("msitest"), "File not deleted\n");
3654     }
3655
3656     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3657     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3658
3659     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3660     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3661
3662     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3663     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3664
3665     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3666                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3667     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3668     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3669
3670     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3671     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3672
3673     /* make sure 'Program Files\msitest' is removed */
3674     delete_pfmsitest_files();
3675
3676     RegCloseKey(uninstall);
3677     DeleteFile(msifile);
3678     DeleteFile("msitest\\maximus");
3679     RemoveDirectory("msitest");
3680 }
3681
3682 static void test_publishsourcelist(void)
3683 {
3684     UINT r;
3685     DWORD size;
3686     CHAR value[MAX_PATH];
3687     CHAR path[MAX_PATH];
3688     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3689
3690     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
3691     {
3692         skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
3693         return;
3694     }
3695
3696     CreateDirectoryA("msitest", NULL);
3697     create_file("msitest\\maximus", 500);
3698
3699     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3700
3701     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3702
3703     r = MsiInstallProductA(msifile, NULL);
3704     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3705     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3706     ok(pf_exists("msitest"), "File not installed\n");
3707
3708     /* nothing published */
3709     size = 0xdeadbeef;
3710     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3711                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3712     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3713     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3714
3715     size = 0xdeadbeef;
3716     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3717                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3718     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3719     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3720
3721     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
3722     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3723     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3724     ok(pf_exists("msitest"), "File not installed\n");
3725
3726     /* after RegisterProduct */
3727     size = 0xdeadbeef;
3728     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3729                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3730     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3731     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3732
3733     size = 0xdeadbeef;
3734     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3735                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3736     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3737     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3738
3739     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3741     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3742     ok(pf_exists("msitest"), "File not installed\n");
3743
3744     /* after ProcessComponents */
3745     size = 0xdeadbeef;
3746     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3747                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3748     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3749     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3750
3751     size = 0xdeadbeef;
3752     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3753                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3754     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3755     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3756
3757     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3759     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3760     ok(pf_exists("msitest"), "File not installed\n");
3761
3762     /* after PublishFeatures */
3763     size = 0xdeadbeef;
3764     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3765                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3766     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3767     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3768
3769     size = 0xdeadbeef;
3770     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3771                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3772     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3773     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3774
3775     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3777     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3778     ok(pf_exists("msitest"), "File not installed\n");
3779
3780     /* after PublishProduct */
3781     size = MAX_PATH;
3782     lstrcpyA(value, "aaa");
3783     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3784                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
3785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3786     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
3787     ok(size == 11, "Expected 11, got %d\n", size);
3788
3789     size = MAX_PATH;
3790     lstrcpyA(value, "aaa");
3791     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3792                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
3793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3794     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3795     ok(size == 0, "Expected 0, got %d\n", size);
3796
3797     size = MAX_PATH;
3798     lstrcpyA(value, "aaa");
3799     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3800                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
3801     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3802     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3803     ok(size == 0, "Expected 0, got %d\n", size);
3804
3805     lstrcpyA(path, CURR_DIR);
3806     lstrcatA(path, "\\");
3807
3808     size = MAX_PATH;
3809     lstrcpyA(value, "aaa");
3810     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3811                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3812     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3813     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3814     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3815
3816     size = MAX_PATH;
3817     lstrcpyA(value, "aaa");
3818     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3819                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
3820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3821     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
3822     ok(size == 1, "Expected 1, got %d\n", size);
3823
3824     size = MAX_PATH;
3825     lstrcpyA(value, "aaa");
3826     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3827                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
3828     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3829     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3830     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3831
3832     size = MAX_PATH;
3833     lstrcpyA(value, "aaa");
3834     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3835                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
3836     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3837     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3838     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3839
3840     size = MAX_PATH;
3841     lstrcpyA(value, "aaa");
3842     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3843                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
3844     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3845     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3846     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3847
3848     /* complete uninstall */
3849     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3851     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3852     todo_wine
3853     {
3854         ok(!pf_exists("msitest"), "File not deleted\n");
3855     }
3856
3857     /* make sure 'Program Files\msitest' is removed */
3858     delete_pfmsitest_files();
3859
3860     DeleteFile(msifile);
3861     DeleteFile("msitest\\maximus");
3862     RemoveDirectory("msitest");
3863 }
3864
3865 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
3866 {
3867     MSIHANDLE hview = 0;
3868     UINT r;
3869
3870     r = MsiDatabaseOpenView(hdb, query, &hview);
3871     if(r != ERROR_SUCCESS)
3872         return r;
3873
3874     r = MsiViewExecute(hview, hrec);
3875     if(r == ERROR_SUCCESS)
3876         r = MsiViewClose(hview);
3877     MsiCloseHandle(hview);
3878     return r;
3879 }
3880
3881 static void set_transform_summary_info(void)
3882 {
3883     UINT r;
3884     MSIHANDLE suminfo = 0;
3885
3886     /* build summary info */
3887     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
3888     todo_wine
3889     {
3890         ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
3891     }
3892
3893     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3894     todo_wine
3895     {
3896         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3897     }
3898
3899     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3900                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3901                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3902                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
3903     todo_wine
3904     {
3905         ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
3906     }
3907
3908     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3909     todo_wine
3910     {
3911         ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3912     }
3913
3914     r = MsiSummaryInfoPersist(suminfo);
3915     todo_wine
3916     {
3917         ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
3918     }
3919
3920     r = MsiCloseHandle(suminfo);
3921     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
3922 }
3923
3924 static void generate_transform(void)
3925 {
3926     MSIHANDLE hdb1, hdb2;
3927     LPCSTR query;
3928     UINT r;
3929
3930     /* start with two identical databases */
3931     CopyFile(msifile, msifile2, FALSE);
3932
3933     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
3934     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3935
3936     r = MsiDatabaseCommit(hdb1);
3937     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
3938
3939     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
3940     ok(r == ERROR_SUCCESS , "Failed to create database\n");
3941
3942     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
3943     r = run_query(hdb1, 0, query);
3944     ok(r == ERROR_SUCCESS, "failed to add property\n");
3945
3946     /* database needs to be committed */
3947     MsiDatabaseCommit(hdb1);
3948
3949     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
3950     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
3951
3952 #if 0  /* not implemented in wine yet */
3953     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
3954     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3955 #endif
3956
3957     MsiCloseHandle(hdb1);
3958     MsiCloseHandle(hdb2);
3959 }
3960
3961 /* data for generating a transform */
3962
3963 /* tables transform names - encoded as they would be in an msi database file */
3964 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3965 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3966 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3967
3968 /* data in each table */
3969 static const char data1[] = /* _StringData */
3970     "propval";  /* all the strings squashed together */
3971
3972 static const WCHAR data2[] = { /* _StringPool */
3973 /*  len, refs */
3974     0,   0,    /* string 0 ''     */
3975     4,   1,    /* string 1 'prop' */
3976     3,   1,    /* string 2 'val'  */
3977 };
3978
3979 static const WCHAR data3[] = { /* Property */
3980     0x0201, 0x0001, 0x0002,
3981 };
3982
3983 static const struct {
3984     LPCWSTR name;
3985     const void *data;
3986     DWORD size;
3987 } table_transform_data[] =
3988 {
3989     { name1, data1, sizeof data1 - 1 },
3990     { name2, data2, sizeof data2 },
3991     { name3, data3, sizeof data3 },
3992 };
3993
3994 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
3995
3996 static void generate_transform_manual(void)
3997 {
3998     IStorage *stg = NULL;
3999     IStream *stm;
4000     WCHAR name[0x20];
4001     HRESULT r;
4002     DWORD i, count;
4003     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
4004
4005     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
4006
4007     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
4008
4009     r = StgCreateDocfile(name, mode, 0, &stg);
4010     ok(r == S_OK, "failed to create storage\n");
4011     if (!stg)
4012         return;
4013
4014     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
4015     ok(r == S_OK, "failed to set storage type\n");
4016
4017     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
4018     {
4019         r = IStorage_CreateStream(stg, table_transform_data[i].name,
4020                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4021         if (FAILED(r))
4022         {
4023             ok(0, "failed to create stream %08x\n", r);
4024             continue;
4025         }
4026
4027         r = IStream_Write(stm, table_transform_data[i].data,
4028                           table_transform_data[i].size, &count);
4029         if (FAILED(r) || count != table_transform_data[i].size)
4030             ok(0, "failed to write stream\n");
4031         IStream_Release(stm);
4032     }
4033
4034     IStorage_Release(stg);
4035
4036     set_transform_summary_info();
4037 }
4038
4039 static void test_transformprop(void)
4040 {
4041     UINT r;
4042
4043     CreateDirectoryA("msitest", NULL);
4044     create_file("msitest\\augustus", 500);
4045
4046     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
4047
4048     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4049
4050     r = MsiInstallProductA(msifile, NULL);
4051     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4052     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4053     ok(!delete_pf("msitest", FALSE), "File installed\n");
4054
4055     if (0)
4056         generate_transform();
4057     else
4058         generate_transform_manual();
4059
4060     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
4061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4062     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4063     ok(delete_pf("msitest", FALSE), "File not installed\n");
4064
4065     /* Delete the files in the temp (current) folder */
4066     DeleteFile(msifile);
4067     DeleteFile(msifile2);
4068     DeleteFile(mstfile);
4069     DeleteFile("msitest\\augustus");
4070     RemoveDirectory("msitest");
4071 }
4072
4073 static void test_currentworkingdir(void)
4074 {
4075     UINT r;
4076     CHAR path[MAX_PATH];
4077     LPSTR ptr, ptr2;
4078
4079     CreateDirectoryA("msitest", NULL);
4080     create_file("msitest\\augustus", 500);
4081
4082     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
4083
4084     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4085
4086     CreateDirectoryA("diffdir", NULL);
4087     SetCurrentDirectoryA("diffdir");
4088
4089     sprintf(path, "..\\%s", msifile);
4090     r = MsiInstallProductA(path, NULL);
4091     todo_wine
4092     {
4093         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
4094         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4095         ok(!delete_pf("msitest", FALSE), "File installed\n");
4096     }
4097
4098     sprintf(path, "%s\\%s", CURR_DIR, msifile);
4099     r = MsiInstallProductA(path, NULL);
4100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4101     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4102     ok(delete_pf("msitest", FALSE), "File not installed\n");
4103
4104     lstrcpyA(path, CURR_DIR);
4105     if (path[lstrlenA(path) - 1] != '\\')
4106         lstrcatA(path, "\\");
4107     lstrcatA(path, "msitest.msi");
4108
4109     ptr2 = strrchr(path, '\\');
4110     *ptr2 = '\0';
4111     ptr = strrchr(path, '\\');
4112     *ptr2 = '\\';
4113     *(ptr++) = '\0';
4114
4115     SetCurrentDirectoryA(path);
4116
4117     r = MsiInstallProductA(ptr, NULL);
4118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4119     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4120     ok(delete_pf("msitest", FALSE), "File not installed\n");
4121
4122     SetCurrentDirectoryA(CURR_DIR);
4123
4124     DeleteFile(msifile);
4125     DeleteFile("msitest\\augustus");
4126     RemoveDirectory("msitest");
4127     RemoveDirectory("diffdir");
4128 }
4129
4130 static void set_admin_summary_info(const CHAR *name)
4131 {
4132     MSIHANDLE db, summary;
4133     UINT r;
4134
4135     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
4136     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4137
4138     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
4139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4140
4141     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
4142     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4143
4144     /* write the summary changes back to the stream */
4145     r = MsiSummaryInfoPersist(summary);
4146     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4147
4148     MsiCloseHandle(summary);
4149
4150     r = MsiDatabaseCommit(db);
4151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4152
4153     MsiCloseHandle(db);
4154 }
4155
4156 static void test_admin(void)
4157 {
4158     UINT r;
4159
4160     CreateDirectoryA("msitest", NULL);
4161     create_file("msitest\\augustus", 500);
4162
4163     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
4164     set_admin_summary_info(msifile);
4165
4166     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4167
4168     r = MsiInstallProductA(msifile, NULL);
4169     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4170     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4171     ok(!delete_pf("msitest", FALSE), "File installed\n");
4172     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
4173     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
4174
4175     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
4176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4177     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4178     ok(!delete_pf("msitest", FALSE), "File installed\n");
4179     todo_wine
4180     {
4181         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
4182         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
4183     }
4184
4185     DeleteFile(msifile);
4186     DeleteFile("msitest\\augustus");
4187     RemoveDirectory("msitest");
4188 }
4189
4190 static void set_admin_property_stream(LPCSTR file)
4191 {
4192     IStorage *stg;
4193     IStream *stm;
4194     WCHAR fileW[MAX_PATH];
4195     HRESULT hr;
4196     DWORD count;
4197     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
4198
4199     /* AdminProperties */
4200     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
4201     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
4202
4203     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
4204
4205     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
4206     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4207     if (!stg)
4208         return;
4209
4210     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4211     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4212
4213     hr = IStream_Write(stm, data, sizeof(data), &count);
4214     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4215
4216     IStream_Release(stm);
4217     IStorage_Release(stg);
4218 }
4219
4220 static void test_adminprops(void)
4221 {
4222     UINT r;
4223
4224     CreateDirectoryA("msitest", NULL);
4225     create_file("msitest\\augustus", 500);
4226
4227     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
4228     set_admin_summary_info(msifile);
4229     set_admin_property_stream(msifile);
4230
4231     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4232
4233     r = MsiInstallProductA(msifile, NULL);
4234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4235     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4236     ok(delete_pf("msitest", FALSE), "File installed\n");
4237
4238     DeleteFile(msifile);
4239     DeleteFile("msitest\\augustus");
4240     RemoveDirectory("msitest");
4241 }
4242
4243 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4244 {
4245     CHAR path[MAX_PATH];
4246
4247     lstrcpyA(path, PROG_FILES_DIR);
4248     lstrcatA(path, "\\");
4249     lstrcatA(path, file);
4250
4251     if (is_file)
4252         create_file_data(path, data, 500);
4253     else
4254         CreateDirectoryA(path, NULL);
4255 }
4256
4257 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4258
4259 static void test_removefiles(void)
4260 {
4261     UINT r;
4262
4263     CreateDirectoryA("msitest", NULL);
4264     create_file("msitest\\hydrogen", 500);
4265     create_file("msitest\\helium", 500);
4266     create_file("msitest\\lithium", 500);
4267
4268     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4269
4270     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4271
4272     r = MsiInstallProductA(msifile, NULL);
4273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4274     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4275     ok(!pf_exists("msitest\\helium"), "File installed\n");
4276     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4277     ok(pf_exists("msitest"), "File not installed\n");
4278
4279     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4280     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4281     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4282     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4283     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4284     ok(delete_pf("msitest", FALSE), "File deleted\n");
4285
4286     create_pf("msitest", FALSE);
4287     create_pf("msitest\\hydrogen", TRUE);
4288     create_pf("msitest\\helium", TRUE);
4289     create_pf("msitest\\lithium", TRUE);
4290
4291     r = MsiInstallProductA(msifile, NULL);
4292     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4293     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4294     ok(pf_exists("msitest\\helium"), "File not installed\n");
4295     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4296     ok(pf_exists("msitest"), "File not installed\n");
4297
4298     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4299     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4300     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4301     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4302     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4303     ok(delete_pf("msitest", FALSE), "File deleted\n");
4304
4305     create_pf("msitest", FALSE);
4306     create_pf("msitest\\furlong", TRUE);
4307     create_pf("msitest\\firkin", TRUE);
4308     create_pf("msitest\\fortnight", TRUE);
4309     create_pf("msitest\\becquerel", TRUE);
4310     create_pf("msitest\\dioptre", TRUE);
4311     create_pf("msitest\\attoparsec", TRUE);
4312     create_pf("msitest\\storeys", TRUE);
4313     create_pf("msitest\\block", TRUE);
4314     create_pf("msitest\\siriometer", TRUE);
4315     create_pf("msitest\\cabout", FALSE);
4316     create_pf("msitest\\cabout\\blocker", TRUE);
4317
4318     r = MsiInstallProductA(msifile, NULL);
4319     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4320     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4321     ok(!pf_exists("msitest\\helium"), "File installed\n");
4322     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4323     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4324     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4325     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4326     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4327     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4328     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4329     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4330     ok(!pf_exists("msitest\\block"), "File not deleted\n");
4331     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4332     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
4333     ok(pf_exists("msitest"), "File not installed\n");
4334
4335     create_pf("msitest\\furlong", TRUE);
4336     create_pf("msitest\\firkin", TRUE);
4337     create_pf("msitest\\fortnight", TRUE);
4338     create_pf("msitest\\storeys", TRUE);
4339     create_pf("msitest\\block", TRUE);
4340     create_pf("msitest\\siriometer", TRUE);
4341
4342     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4344     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4345     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4346     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4347     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4348     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4349     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4350     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4351     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4352     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4353     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4354     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4355     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4356     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4357     ok(pf_exists("msitest"), "Directory deleted\n");
4358
4359     r = MsiInstallProductA(msifile, NULL);
4360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4361     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
4362     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
4363     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
4364     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4365     ok(pf_exists("msitest"), "Directory deleted\n");
4366
4367     delete_pf("msitest\\cabout\\blocker", TRUE);
4368
4369     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4371     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
4372     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4373
4374     DeleteFile(msifile);
4375     DeleteFile("msitest\\hydrogen");
4376     DeleteFile("msitest\\helium");
4377     DeleteFile("msitest\\lithium");
4378     RemoveDirectory("msitest");
4379 }
4380
4381 static void test_movefiles(void)
4382 {
4383     UINT r;
4384     char props[MAX_PATH];
4385
4386     CreateDirectoryA("msitest", NULL);
4387     create_file("msitest\\augustus", 100);
4388     create_file("cameroon", 100);
4389     create_file("djibouti", 100);
4390     create_file("egypt", 100);
4391     create_file("finland", 100);
4392     create_file("gambai", 100);
4393     create_file("honduras", 100);
4394     create_file("msitest\\india", 100);
4395     create_file("japan", 100);
4396     create_file("kenya", 100);
4397     CreateDirectoryA("latvia", NULL);
4398     create_file("nauru", 100);
4399     create_file("peru", 100);
4400     create_file("apple", 100);
4401     create_file("application", 100);
4402     create_file("ape", 100);
4403     create_file("foo", 100);
4404     create_file("fao", 100);
4405     create_file("fbod", 100);
4406     create_file("budding", 100);
4407     create_file("buddy", 100);
4408     create_file("bud", 100);
4409     create_file("bar", 100);
4410     create_file("bur", 100);
4411     create_file("bird", 100);
4412
4413     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4414
4415     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4416
4417     /* if the source or dest property is not a full path,
4418      * windows tries to access it as a network resource
4419      */
4420
4421     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4422             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4423             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4424
4425     r = MsiInstallProductA(msifile, props);
4426     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4427     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4428     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4429     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4430     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4431     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4432     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4433     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4434     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4435     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4436     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4437     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4438     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4439     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4440     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
4441     /* either apple or application will be moved depending on directory order */
4442     if (!delete_pf("msitest\\apple", TRUE))
4443         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4444     else
4445         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4446     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4447     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4448     /* either fao or foo will be moved depending on directory order */
4449     if (delete_pf("msitest\\foo", TRUE))
4450         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4451     else
4452         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4453     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4454     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4455     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4456     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4457     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4458     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4459     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4460     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4461     ok(delete_pf("msitest", FALSE), "File not installed\n");
4462     ok(DeleteFileA("cameroon"), "File moved\n");
4463     ok(!DeleteFileA("djibouti"), "File not moved\n");
4464     ok(DeleteFileA("egypt"), "File moved\n");
4465     ok(DeleteFileA("finland"), "File moved\n");
4466     ok(DeleteFileA("gambai"), "File moved\n");
4467     ok(!DeleteFileA("honduras"), "File not moved\n");
4468     ok(DeleteFileA("msitest\\india"), "File moved\n");
4469     ok(DeleteFileA("japan"), "File moved\n");
4470     ok(!DeleteFileA("kenya"), "File not moved\n");
4471     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4472     ok(!DeleteFileA("nauru"), "File not moved\n");
4473     ok(!DeleteFileA("peru"), "File not moved\n");
4474     ok(!DeleteFileA("apple"), "File not moved\n");
4475     ok(!DeleteFileA("application"), "File not moved\n");
4476     ok(DeleteFileA("ape"), "File moved\n");
4477     ok(!DeleteFileA("foo"), "File not moved\n");
4478     ok(!DeleteFileA("fao"), "File not moved\n");
4479     ok(DeleteFileA("fbod"), "File moved\n");
4480     ok(!DeleteFileA("budding"), "File not moved\n");
4481     ok(!DeleteFileA("buddy"), "File not moved\n");
4482     ok(DeleteFileA("bud"), "File moved\n");
4483     ok(!DeleteFileA("bar"), "File not moved\n");
4484     ok(!DeleteFileA("bur"), "File not moved\n");
4485     ok(DeleteFileA("bird"), "File moved\n");
4486
4487     DeleteFile("msitest\\augustus");
4488     RemoveDirectory("msitest");
4489     DeleteFile(msifile);
4490 }
4491
4492 static void test_missingcab(void)
4493 {
4494     UINT r;
4495
4496     CreateDirectoryA("msitest", NULL);
4497     create_file("msitest\\augustus", 500);
4498     create_file("maximus", 500);
4499
4500     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
4501
4502     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4503
4504     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4505
4506     create_pf("msitest", FALSE);
4507     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4508
4509     r = MsiInstallProductA(msifile, NULL);
4510     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4511     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4512     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4513     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4514     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
4515     ok(delete_pf("msitest", FALSE), "File not installed\n");
4516
4517     create_pf("msitest", FALSE);
4518     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4519     create_pf("msitest\\gaius", TRUE);
4520
4521     r = MsiInstallProductA(msifile, "GAIUS=1");
4522     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4523     todo_wine
4524     {
4525         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
4526         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4527     }
4528     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
4529     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
4530     ok(delete_pf("msitest", FALSE), "File not installed\n");
4531
4532     DeleteFile("msitest\\augustus");
4533     RemoveDirectory("msitest");
4534     DeleteFile("maximus");
4535     DeleteFile("test1.cab");
4536     DeleteFile(msifile);
4537 }
4538
4539 static void test_duplicatefiles(void)
4540 {
4541     UINT r;
4542
4543     CreateDirectoryA("msitest", NULL);
4544     create_file("msitest\\maximus", 500);
4545     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4546
4547     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4548
4549     /* fails if the destination folder is not a valid property */
4550
4551     r = MsiInstallProductA(msifile, NULL);
4552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4553     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4554     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4555     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4556     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
4557     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
4558     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
4559     ok(delete_pf("msitest", FALSE), "File not installed\n");
4560
4561     DeleteFile("msitest\\maximus");
4562     RemoveDirectory("msitest");
4563     DeleteFile(msifile);
4564 }
4565
4566 static void test_writeregistryvalues(void)
4567 {
4568     UINT r;
4569     LONG res;
4570     HKEY hkey;
4571     DWORD type, size;
4572     CHAR path[MAX_PATH];
4573
4574     CreateDirectoryA("msitest", NULL);
4575     create_file("msitest\\augustus", 500);
4576
4577     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4578
4579     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4580
4581     r = MsiInstallProductA(msifile, NULL);
4582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4583     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4584     ok(delete_pf("msitest", FALSE), "File installed\n");
4585
4586     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
4587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4588
4589     size = MAX_PATH;
4590     type = REG_MULTI_SZ;
4591     memset(path, 'a', MAX_PATH);
4592     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4594     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4595     ok(size == 15, "Expected 15, got %d\n", size);
4596     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4597
4598     DeleteFile(msifile);
4599     DeleteFile("msitest\\augustus");
4600     RemoveDirectory("msitest");
4601
4602     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
4603     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
4604 }
4605
4606 static void test_sourcefolder(void)
4607 {
4608     UINT r;
4609
4610     CreateDirectoryA("msitest", NULL);
4611     create_file("augustus", 500);
4612
4613     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
4614
4615     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4616
4617     r = MsiInstallProductA(msifile, NULL);
4618     ok(r == ERROR_INSTALL_FAILURE,
4619        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4620     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4621     todo_wine
4622     {
4623         ok(!delete_pf("msitest", FALSE), "File installed\n");
4624     }
4625
4626     RemoveDirectoryA("msitest");
4627
4628     r = MsiInstallProductA(msifile, NULL);
4629     ok(r == ERROR_INSTALL_FAILURE,
4630        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4631     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4632     todo_wine
4633     {
4634         ok(!delete_pf("msitest", FALSE), "File installed\n");
4635     }
4636
4637     DeleteFile(msifile);
4638     DeleteFile("augustus");
4639 }
4640
4641 static void test_customaction51(void)
4642 {
4643     UINT r;
4644
4645     CreateDirectoryA("msitest", NULL);
4646     create_file("msitest\\augustus", 500);
4647
4648     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
4649
4650     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4651
4652     r = MsiInstallProductA(msifile, NULL);
4653     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4654     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4655     ok(delete_pf("msitest", FALSE), "File installed\n");
4656
4657     DeleteFile(msifile);
4658     DeleteFile("msitest\\augustus");
4659     RemoveDirectory("msitest");
4660 }
4661
4662 static void test_installstate(void)
4663 {
4664     UINT r;
4665
4666     CreateDirectoryA("msitest", NULL);
4667     create_file("msitest\\alpha", 500);
4668     create_file("msitest\\beta", 500);
4669     create_file("msitest\\gamma", 500);
4670     create_file("msitest\\theta", 500);
4671     create_file("msitest\\delta", 500);
4672     create_file("msitest\\epsilon", 500);
4673     create_file("msitest\\zeta", 500);
4674     create_file("msitest\\iota", 500);
4675     create_file("msitest\\eta", 500);
4676     create_file("msitest\\kappa", 500);
4677     create_file("msitest\\lambda", 500);
4678     create_file("msitest\\mu", 500);
4679
4680     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
4681
4682     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4683
4684     r = MsiInstallProductA(msifile, NULL);
4685     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4686     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4687     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4688     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4689     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4690     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4691     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4692     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4693     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4694     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4695     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4696     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4697     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4698     ok(delete_pf("msitest", FALSE), "File not installed\n");
4699
4700     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
4701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4702     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4703     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4704     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4705     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4706     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4707     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
4708     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4709     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4710     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
4711     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4712     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4713     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4714     ok(delete_pf("msitest", FALSE), "File not installed\n");
4715
4716     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
4717     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4718     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4719     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4720     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4721     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4722     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4723     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4724     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4725     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4726     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4727     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4728     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4729     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4730     ok(delete_pf("msitest", FALSE), "File not installed\n");
4731
4732     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
4733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4734     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
4735     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4736     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4737     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
4738     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4739     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4740     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4741     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4742     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4743     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4744     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4745     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4746     ok(!delete_pf("msitest", FALSE), "File installed\n");
4747
4748     DeleteFile(msifile);
4749     DeleteFile("msitest\\alpha");
4750     DeleteFile("msitest\\beta");
4751     DeleteFile("msitest\\gamma");
4752     DeleteFile("msitest\\theta");
4753     DeleteFile("msitest\\delta");
4754     DeleteFile("msitest\\epsilon");
4755     DeleteFile("msitest\\zeta");
4756     DeleteFile("msitest\\iota");
4757     DeleteFile("msitest\\eta");
4758     DeleteFile("msitest\\kappa");
4759     DeleteFile("msitest\\lambda");
4760     DeleteFile("msitest\\mu");
4761     RemoveDirectory("msitest");
4762 }
4763
4764 struct sourcepathmap
4765 {
4766     BOOL sost; /* shortone\shorttwo */
4767     BOOL solt; /* shortone\longtwo */
4768     BOOL lost; /* longone\shorttwo */
4769     BOOL lolt; /* longone\longtwo */
4770     BOOL soste; /* shortone\shorttwo source exists */
4771     BOOL solte; /* shortone\longtwo source exists */
4772     BOOL loste; /* longone\shorttwo source exists */
4773     BOOL lolte; /* longone\longtwo source exists */
4774     UINT err;
4775     DWORD size;
4776 } spmap[256] =
4777 {
4778     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4779     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4780     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4781     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4782     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4783     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4784     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4785     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4786     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4787     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4788     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4789     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4790     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4791     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4792     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4793     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4794     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4795     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4796     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4797     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4798     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4799     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4800     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4801     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4802     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4803     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4804     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4805     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4806     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4807     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4808     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4809     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4810     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4811     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4812     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4813     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4814     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4815     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4816     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4817     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4818     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4819     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4820     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4821     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4822     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4823     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4824     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4825     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4826     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4827     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4828     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4829     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4830     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4831     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4832     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4833     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4834     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4835     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4836     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4837     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4838     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4839     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4840     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4841     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4842     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4843     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4844     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4845     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4846     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4847     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4848     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4849     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4850     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4851     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4852     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4853     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4854     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4855     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4856     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4857     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4858     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4859     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4860     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4861     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4862     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4863     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4864     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4865     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4866     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4867     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4868     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4869     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4870     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4871     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4872     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4873     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4874     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4875     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4876     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4877     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4878     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4879     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4880     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4881     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4882     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4883     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4884     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4885     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4886     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4887     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4888     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4889     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4890     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4891     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4892     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4893     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4894     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4895     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4896     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4897     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4898     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4899     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4900     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4901     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4902     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4903     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4904     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4905     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4906     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4907     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4908     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4909     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4910     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4911     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4912     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4913     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4914     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4915     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4916     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4917     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4918     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4919     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4920     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4921     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4922     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4923     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4924     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4925     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4926     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4927     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4928     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4929     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4930     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4931     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4932     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4933     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4934     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4935     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4936     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4937     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4938     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4939     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4940     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4941     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4942     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4943     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4944     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4945     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4946     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4947     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4948     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4949     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4950     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4951     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4952     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4953     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4954     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4955     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4956     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4957     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4958     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4959     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4960     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4961     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4962     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4963     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4964     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4965     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4966     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4967     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4968     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4969     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4970     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4971     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4972     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4973     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4974     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4975     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4976     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4977     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4978     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4979     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4980     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4981     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4982     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4983     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4984     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4985     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4986     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4987     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4988     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4989     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4990     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4991     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4992     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4993     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4994     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4995     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4996     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4997     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4998     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4999     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5000     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5001     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5002     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5003     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5004     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5005     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5006     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5007     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5008     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5009     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5010     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5011     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5012     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5013     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5014     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5015     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5016     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5017     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5018     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5019     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5020     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5021     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5022     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5023     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5024     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5025     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5026     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5027     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5028     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5029     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5030     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5031     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5032     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5033     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5034 };
5035
5036 static DWORD get_pf_file_size(LPCSTR file)
5037 {
5038     CHAR path[MAX_PATH];
5039     HANDLE hfile;
5040     DWORD size;
5041
5042     lstrcpyA(path, PROG_FILES_DIR);
5043     lstrcatA(path, "\\");
5044     lstrcatA(path, file);
5045
5046     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
5047     if (hfile == INVALID_HANDLE_VALUE)
5048         return 0;
5049
5050     size = GetFileSize(hfile, NULL);
5051     CloseHandle(hfile);
5052     return size;
5053 }
5054
5055 static void test_sourcepath(void)
5056 {
5057     UINT r, i;
5058
5059     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
5060
5061     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5062
5063     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
5064     {
5065         if (spmap[i].sost)
5066         {
5067             CreateDirectoryA("shortone", NULL);
5068             CreateDirectoryA("shortone\\shorttwo", NULL);
5069         }
5070
5071         if (spmap[i].solt)
5072         {
5073             CreateDirectoryA("shortone", NULL);
5074             CreateDirectoryA("shortone\\longtwo", NULL);
5075         }
5076
5077         if (spmap[i].lost)
5078         {
5079             CreateDirectoryA("longone", NULL);
5080             CreateDirectoryA("longone\\shorttwo", NULL);
5081         }
5082
5083         if (spmap[i].lolt)
5084         {
5085             CreateDirectoryA("longone", NULL);
5086             CreateDirectoryA("longone\\longtwo", NULL);
5087         }
5088
5089         if (spmap[i].soste)
5090             create_file("shortone\\shorttwo\\augustus", 50);
5091         if (spmap[i].solte)
5092             create_file("shortone\\longtwo\\augustus", 100);
5093         if (spmap[i].loste)
5094             create_file("longone\\shorttwo\\augustus", 150);
5095         if (spmap[i].lolte)
5096             create_file("longone\\longtwo\\augustus", 200);
5097
5098         r = MsiInstallProductA(msifile, NULL);
5099         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
5100         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
5101            "%d: Expected %d, got %d\n", i, spmap[i].size,
5102            get_pf_file_size("msitest\\augustus"));
5103
5104         if (r == ERROR_SUCCESS)
5105         {
5106             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
5107             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
5108         }
5109         else
5110         {
5111             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
5112             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
5113         }
5114
5115         DeleteFileA("shortone\\shorttwo\\augustus");
5116         DeleteFileA("shortone\\longtwo\\augustus");
5117         DeleteFileA("longone\\shorttwo\\augustus");
5118         DeleteFileA("longone\\longtwo\\augustus");
5119         RemoveDirectoryA("shortone\\shorttwo");
5120         RemoveDirectoryA("shortone\\longtwo");
5121         RemoveDirectoryA("longone\\shorttwo");
5122         RemoveDirectoryA("longone\\longtwo");
5123         RemoveDirectoryA("shortone");
5124         RemoveDirectoryA("longone");
5125     }
5126
5127     DeleteFileA(msifile);
5128 }
5129
5130 static void test_MsiConfigureProductEx(void)
5131 {
5132     UINT r;
5133     LONG res;
5134     DWORD type, size;
5135     HKEY props, source;
5136     CHAR keypath[MAX_PATH * 2];
5137     CHAR localpack[MAX_PATH];
5138
5139     CreateDirectoryA("msitest", NULL);
5140     create_file("msitest\\hydrogen", 500);
5141     create_file("msitest\\helium", 500);
5142     create_file("msitest\\lithium", 500);
5143
5144     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5145
5146     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5147
5148     /* NULL szProduct */
5149     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
5150                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5151     ok(r == ERROR_INVALID_PARAMETER,
5152        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5153
5154     /* empty szProduct */
5155     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
5156                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5157     ok(r == ERROR_INVALID_PARAMETER,
5158        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5159
5160     /* garbage szProduct */
5161     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
5162                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5163     ok(r == ERROR_INVALID_PARAMETER,
5164        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5165
5166     /* guid without brackets */
5167     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
5168                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5169                                "PROPVAR=42");
5170     ok(r == ERROR_INVALID_PARAMETER,
5171        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5172
5173     /* guid with brackets */
5174     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
5175                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5176                                "PROPVAR=42");
5177     ok(r == ERROR_UNKNOWN_PRODUCT,
5178        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5179
5180     /* same length as guid, but random */
5181     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
5182                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5183                                "PROPVAR=42");
5184     ok(r == ERROR_UNKNOWN_PRODUCT,
5185        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5186
5187     /* product not installed yet */
5188     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5189                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5190                                "PROPVAR=42");
5191     ok(r == ERROR_UNKNOWN_PRODUCT,
5192        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5193
5194     /* install the product, per-user unmanaged */
5195     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
5196     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5197     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5198     ok(pf_exists("msitest\\helium"), "File not installed\n");
5199     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5200     ok(pf_exists("msitest"), "File not installed\n");
5201
5202     /* product is installed per-user managed, remove it */
5203     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5204                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5205                                "PROPVAR=42");
5206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5207     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5208     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5209     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5210     todo_wine
5211     {
5212         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5213     }
5214
5215     /* product has been removed */
5216     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5217                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5218                                "PROPVAR=42");
5219     ok(r == ERROR_UNKNOWN_PRODUCT,
5220        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
5221
5222     /* install the product, machine */
5223     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5225     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5226     ok(pf_exists("msitest\\helium"), "File not installed\n");
5227     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5228     ok(pf_exists("msitest"), "File not installed\n");
5229
5230     /* product is installed machine, remove it */
5231     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5232                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5233                                "PROPVAR=42");
5234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5235     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5236     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5237     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5238     todo_wine
5239     {
5240         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5241     }
5242
5243     /* product has been removed */
5244     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5245                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5246                                "PROPVAR=42");
5247     ok(r == ERROR_UNKNOWN_PRODUCT,
5248        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
5249
5250     /* install the product, machine */
5251     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5253     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5254     ok(pf_exists("msitest\\helium"), "File not installed\n");
5255     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5256     ok(pf_exists("msitest"), "File not installed\n");
5257
5258     DeleteFileA(msifile);
5259
5260     /* local msifile is removed */
5261     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5262                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5263                                "PROPVAR=42");
5264     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5265     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5266     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5267     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5268     todo_wine
5269     {
5270         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5271     }
5272
5273     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5274
5275     /* install the product, machine */
5276     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5278     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5279     ok(pf_exists("msitest\\helium"), "File not installed\n");
5280     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5281     ok(pf_exists("msitest"), "File not installed\n");
5282
5283     DeleteFileA(msifile);
5284
5285     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
5286     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
5287     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
5288
5289     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5291
5292     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
5293                          (const BYTE *)"C:\\idontexist.msi", 18);
5294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5295
5296     /* LocalPackage is used to find the cached msi package */
5297     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5298                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5299                                "PROPVAR=42");
5300     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
5301        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
5302     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5303     ok(pf_exists("msitest\\helium"), "File not installed\n");
5304     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5305     ok(pf_exists("msitest"), "File not installed\n");
5306
5307     RegCloseKey(props);
5308     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5309
5310     /* LastUsedSource (local msi package) can be used as a last resort */
5311     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5312                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5313                                "PROPVAR=42");
5314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5315     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5316     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5317     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5318     todo_wine
5319     {
5320         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5321     }
5322
5323     /* install the product, machine */
5324     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5326     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5327     ok(pf_exists("msitest\\helium"), "File not installed\n");
5328     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5329     ok(pf_exists("msitest"), "File not installed\n");
5330
5331     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
5332     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
5333     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
5334
5335     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5337
5338     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
5339                          (const BYTE *)"C:\\idontexist.msi", 18);
5340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5341
5342     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
5343     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
5344
5345     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
5346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5347
5348     type = REG_SZ;
5349     size = MAX_PATH;
5350     res = RegQueryValueExA(source, "PackageName", NULL, &type,
5351                            (LPBYTE)localpack, &size);
5352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5353
5354     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
5355                          (const BYTE *)"idontexist.msi", 15);
5356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5357
5358     /* SourceList is altered */
5359     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5360                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5361                                "PROPVAR=42");
5362     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
5363        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
5364     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5365     ok(pf_exists("msitest\\helium"), "File not installed\n");
5366     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5367     ok(pf_exists("msitest"), "File not installed\n");
5368
5369     /* restore the SourceList */
5370     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
5371                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
5372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5373
5374     /* finally remove the product */
5375     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5376                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5377                                "PROPVAR=42");
5378     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5379     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5380     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5381     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5382     todo_wine
5383     {
5384         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5385     }
5386
5387     DeleteFileA(msifile);
5388     RegCloseKey(source);
5389     RegCloseKey(props);
5390     DeleteFileA("msitest\\hydrogen");
5391     DeleteFileA("msitest\\helium");
5392     DeleteFileA("msitest\\lithium");
5393     RemoveDirectoryA("msitest");
5394 }
5395
5396 static void test_missingcomponent(void)
5397 {
5398     UINT r;
5399
5400     CreateDirectoryA("msitest", NULL);
5401     create_file("msitest\\hydrogen", 500);
5402     create_file("msitest\\helium", 500);
5403     create_file("msitest\\lithium", 500);
5404     create_file("beryllium", 500);
5405
5406     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
5407
5408     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5409
5410     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
5411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5412     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5413     ok(pf_exists("msitest\\helium"), "File not installed\n");
5414     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5415     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5416     ok(pf_exists("msitest"), "File not installed\n");
5417
5418     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
5419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5420     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5421     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5422     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5423     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5424     todo_wine
5425     {
5426         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5427     }
5428
5429     DeleteFileA(msifile);
5430     DeleteFileA("msitest\\hydrogen");
5431     DeleteFileA("msitest\\helium");
5432     DeleteFileA("msitest\\lithium");
5433     DeleteFileA("beryllium");
5434     RemoveDirectoryA("msitest");
5435 }
5436
5437 START_TEST(install)
5438 {
5439     DWORD len;
5440     char temp_path[MAX_PATH], prev_path[MAX_PATH];
5441     STATEMGRSTATUS status;
5442     BOOL ret = FALSE;
5443
5444     init_functionpointers();
5445
5446     GetCurrentDirectoryA(MAX_PATH, prev_path);
5447     GetTempPath(MAX_PATH, temp_path);
5448     SetCurrentDirectoryA(temp_path);
5449
5450     lstrcpyA(CURR_DIR, temp_path);
5451     len = lstrlenA(CURR_DIR);
5452
5453     if(len && (CURR_DIR[len - 1] == '\\'))
5454         CURR_DIR[len - 1] = 0;
5455
5456     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
5457
5458     /* Create a restore point ourselves so we circumvent the multitude of restore points
5459      * that would have been created by all the installation and removal tests.
5460      */
5461     if (pSRSetRestorePointA)
5462     {
5463         memset(&status, 0, sizeof(status));
5464         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
5465     }
5466
5467     /* Create only one log file and don't append. We have to pass something
5468      * for the log mode for this to work.
5469      */
5470     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, "msitest.log", 0);
5471
5472     test_MsiInstallProduct();
5473     test_MsiSetComponentState();
5474     test_packagecoltypes();
5475     test_continuouscabs();
5476     test_caborder();
5477     test_mixedmedia();
5478     test_samesequence();
5479     test_uiLevelFlags();
5480     test_readonlyfile();
5481     test_setdirproperty();
5482     test_cabisextracted();
5483     test_concurrentinstall();
5484     test_setpropertyfolder();
5485     test_publish_registerproduct();
5486     test_publish_publishproduct();
5487     test_publish_publishfeatures();
5488     test_publish_registeruser();
5489     test_publish_processcomponents();
5490     test_publish();
5491     test_publishsourcelist();
5492     test_transformprop();
5493     test_currentworkingdir();
5494     test_admin();
5495     test_adminprops();
5496     test_removefiles();
5497     test_movefiles();
5498     test_missingcab();
5499     test_duplicatefiles();
5500     test_writeregistryvalues();
5501     test_sourcefolder();
5502     test_customaction51();
5503     test_installstate();
5504     test_sourcepath();
5505     test_MsiConfigureProductEx();
5506     test_missingcomponent();
5507
5508     DeleteFileA("msitest.log");
5509
5510     if (pSRSetRestorePointA && ret)
5511     {
5512         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
5513         if (ret)
5514             remove_restore_point(status.llSequenceNumber);
5515     }
5516     FreeLibrary(hsrclient);
5517
5518     SetCurrentDirectoryA(prev_path);
5519 }