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