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