crypt32/tests: Fix some test failures on Win9x.
[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 drive[MAX_PATH], path[MAX_PATH];
4197     LPSTR ptr;
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(drive, CURR_DIR);
4225     drive[2] = '\\';
4226     drive[3] = '\0';
4227     SetCurrentDirectoryA(drive);
4228
4229     lstrcpy(path, CURR_DIR);
4230     if (path[lstrlenA(path) - 1] != '\\')
4231         lstrcatA(path, "\\");
4232     lstrcatA(path, msifile);
4233     ptr = strchr(path, ':');
4234     ptr +=2;
4235
4236     r = MsiInstallProductA(ptr, NULL);
4237     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4238     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4239     ok(delete_pf("msitest", FALSE), "File not installed\n");
4240
4241     SetCurrentDirectoryA(CURR_DIR);
4242
4243     DeleteFile(msifile);
4244     DeleteFile("msitest\\augustus");
4245     RemoveDirectory("msitest");
4246     RemoveDirectory("diffdir");
4247 }
4248
4249 static void set_admin_summary_info(const CHAR *name)
4250 {
4251     MSIHANDLE db, summary;
4252     UINT r;
4253
4254     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
4255     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4256
4257     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
4258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4259
4260     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
4261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4262
4263     /* write the summary changes back to the stream */
4264     r = MsiSummaryInfoPersist(summary);
4265     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4266
4267     MsiCloseHandle(summary);
4268
4269     r = MsiDatabaseCommit(db);
4270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4271
4272     MsiCloseHandle(db);
4273 }
4274
4275 static void test_admin(void)
4276 {
4277     UINT r;
4278
4279     CreateDirectoryA("msitest", NULL);
4280     create_file("msitest\\augustus", 500);
4281
4282     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
4283     set_admin_summary_info(msifile);
4284
4285     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4286
4287     r = MsiInstallProductA(msifile, NULL);
4288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4289     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4290     ok(!delete_pf("msitest", FALSE), "File installed\n");
4291     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
4292     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
4293
4294     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
4295     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4296     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4297     ok(!delete_pf("msitest", FALSE), "File installed\n");
4298     todo_wine
4299     {
4300         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
4301         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
4302     }
4303
4304     DeleteFile(msifile);
4305     DeleteFile("msitest\\augustus");
4306     RemoveDirectory("msitest");
4307 }
4308
4309 static void set_admin_property_stream(LPCSTR file)
4310 {
4311     IStorage *stg;
4312     IStream *stm;
4313     WCHAR fileW[MAX_PATH];
4314     HRESULT hr;
4315     DWORD count;
4316     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
4317
4318     /* AdminProperties */
4319     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
4320     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
4321         'M','y','P','r','o','p','=','4','2',0};
4322
4323     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
4324
4325     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
4326     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4327     if (!stg)
4328         return;
4329
4330     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4331     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4332
4333     hr = IStream_Write(stm, data, sizeof(data), &count);
4334     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4335
4336     IStream_Release(stm);
4337     IStorage_Release(stg);
4338 }
4339
4340 static void test_adminprops(void)
4341 {
4342     UINT r;
4343
4344     CreateDirectoryA("msitest", NULL);
4345     create_file("msitest\\augustus", 500);
4346
4347     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
4348     set_admin_summary_info(msifile);
4349     set_admin_property_stream(msifile);
4350
4351     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4352
4353     r = MsiInstallProductA(msifile, NULL);
4354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4355     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4356     ok(delete_pf("msitest", FALSE), "File installed\n");
4357
4358     DeleteFile(msifile);
4359     DeleteFile("msitest\\augustus");
4360     RemoveDirectory("msitest");
4361 }
4362
4363 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4364 {
4365     CHAR path[MAX_PATH];
4366
4367     lstrcpyA(path, PROG_FILES_DIR);
4368     lstrcatA(path, "\\");
4369     lstrcatA(path, file);
4370
4371     if (is_file)
4372         create_file_data(path, data, 500);
4373     else
4374         CreateDirectoryA(path, NULL);
4375 }
4376
4377 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4378
4379 static void test_removefiles(void)
4380 {
4381     UINT r;
4382
4383     CreateDirectoryA("msitest", NULL);
4384     create_file("msitest\\hydrogen", 500);
4385     create_file("msitest\\helium", 500);
4386     create_file("msitest\\lithium", 500);
4387
4388     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4389
4390     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4391
4392     r = MsiInstallProductA(msifile, NULL);
4393     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4394     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4395     ok(!pf_exists("msitest\\helium"), "File installed\n");
4396     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4397     ok(pf_exists("msitest"), "File not installed\n");
4398
4399     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4401     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4402     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4403     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4404     ok(delete_pf("msitest", FALSE), "File deleted\n");
4405
4406     create_pf("msitest", FALSE);
4407     create_pf("msitest\\hydrogen", TRUE);
4408     create_pf("msitest\\helium", TRUE);
4409     create_pf("msitest\\lithium", TRUE);
4410
4411     r = MsiInstallProductA(msifile, NULL);
4412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4413     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4414     ok(pf_exists("msitest\\helium"), "File not installed\n");
4415     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4416     ok(pf_exists("msitest"), "File not installed\n");
4417
4418     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4420     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4421     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4422     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4423     ok(delete_pf("msitest", FALSE), "File deleted\n");
4424
4425     create_pf("msitest", FALSE);
4426     create_pf("msitest\\furlong", TRUE);
4427     create_pf("msitest\\firkin", TRUE);
4428     create_pf("msitest\\fortnight", TRUE);
4429     create_pf("msitest\\becquerel", TRUE);
4430     create_pf("msitest\\dioptre", TRUE);
4431     create_pf("msitest\\attoparsec", TRUE);
4432     create_pf("msitest\\storeys", TRUE);
4433     create_pf("msitest\\block", TRUE);
4434     create_pf("msitest\\siriometer", TRUE);
4435     create_pf("msitest\\cabout", FALSE);
4436     create_pf("msitest\\cabout\\blocker", TRUE);
4437
4438     r = MsiInstallProductA(msifile, NULL);
4439     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4440     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4441     ok(!pf_exists("msitest\\helium"), "File installed\n");
4442     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4443     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4444     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4445     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4446     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4447     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4448     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4449     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4450     ok(!pf_exists("msitest\\block"), "File not deleted\n");
4451     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4452     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
4453     ok(pf_exists("msitest"), "File not installed\n");
4454
4455     create_pf("msitest\\furlong", TRUE);
4456     create_pf("msitest\\firkin", TRUE);
4457     create_pf("msitest\\fortnight", TRUE);
4458     create_pf("msitest\\storeys", TRUE);
4459     create_pf("msitest\\block", TRUE);
4460     create_pf("msitest\\siriometer", TRUE);
4461
4462     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4464     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4465     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4466     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4467     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4468     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4469     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4470     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4471     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4472     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4473     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4474     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4475     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4476     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4477     ok(pf_exists("msitest"), "Directory deleted\n");
4478
4479     r = MsiInstallProductA(msifile, NULL);
4480     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4481     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
4482     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
4483     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
4484     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4485     ok(pf_exists("msitest"), "Directory deleted\n");
4486
4487     delete_pf("msitest\\cabout\\blocker", TRUE);
4488
4489     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4490     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4491     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
4492     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4493
4494     DeleteFile(msifile);
4495     DeleteFile("msitest\\hydrogen");
4496     DeleteFile("msitest\\helium");
4497     DeleteFile("msitest\\lithium");
4498     RemoveDirectory("msitest");
4499 }
4500
4501 static void test_movefiles(void)
4502 {
4503     UINT r;
4504     char props[MAX_PATH];
4505
4506     CreateDirectoryA("msitest", NULL);
4507     create_file("msitest\\augustus", 100);
4508     create_file("cameroon", 100);
4509     create_file("djibouti", 100);
4510     create_file("egypt", 100);
4511     create_file("finland", 100);
4512     create_file("gambai", 100);
4513     create_file("honduras", 100);
4514     create_file("msitest\\india", 100);
4515     create_file("japan", 100);
4516     create_file("kenya", 100);
4517     CreateDirectoryA("latvia", NULL);
4518     create_file("nauru", 100);
4519     create_file("peru", 100);
4520     create_file("apple", 100);
4521     create_file("application", 100);
4522     create_file("ape", 100);
4523     create_file("foo", 100);
4524     create_file("fao", 100);
4525     create_file("fbod", 100);
4526     create_file("budding", 100);
4527     create_file("buddy", 100);
4528     create_file("bud", 100);
4529     create_file("bar", 100);
4530     create_file("bur", 100);
4531     create_file("bird", 100);
4532
4533     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4534
4535     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4536
4537     /* if the source or dest property is not a full path,
4538      * windows tries to access it as a network resource
4539      */
4540
4541     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4542             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4543             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4544
4545     r = MsiInstallProductA(msifile, props);
4546     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4547     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4548     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4549     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4550     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4551     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4552     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4553     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4554     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4555     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4556     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4557     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4558     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4559     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4560     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
4561     /* either apple or application will be moved depending on directory order */
4562     if (!delete_pf("msitest\\apple", TRUE))
4563         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4564     else
4565         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4566     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4567     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4568     /* either fao or foo will be moved depending on directory order */
4569     if (delete_pf("msitest\\foo", TRUE))
4570         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4571     else
4572         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4573     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4574     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4575     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4576     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4577     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4578     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4579     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4580     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4581     ok(delete_pf("msitest", FALSE), "File not installed\n");
4582     ok(DeleteFileA("cameroon"), "File moved\n");
4583     ok(!DeleteFileA("djibouti"), "File not moved\n");
4584     ok(DeleteFileA("egypt"), "File moved\n");
4585     ok(DeleteFileA("finland"), "File moved\n");
4586     ok(DeleteFileA("gambai"), "File moved\n");
4587     ok(!DeleteFileA("honduras"), "File not moved\n");
4588     ok(DeleteFileA("msitest\\india"), "File moved\n");
4589     ok(DeleteFileA("japan"), "File moved\n");
4590     ok(!DeleteFileA("kenya"), "File not moved\n");
4591     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4592     ok(!DeleteFileA("nauru"), "File not moved\n");
4593     ok(!DeleteFileA("peru"), "File not moved\n");
4594     ok(!DeleteFileA("apple"), "File not moved\n");
4595     ok(!DeleteFileA("application"), "File not moved\n");
4596     ok(DeleteFileA("ape"), "File moved\n");
4597     ok(!DeleteFileA("foo"), "File not moved\n");
4598     ok(!DeleteFileA("fao"), "File not moved\n");
4599     ok(DeleteFileA("fbod"), "File moved\n");
4600     ok(!DeleteFileA("budding"), "File not moved\n");
4601     ok(!DeleteFileA("buddy"), "File not moved\n");
4602     ok(DeleteFileA("bud"), "File moved\n");
4603     ok(!DeleteFileA("bar"), "File not moved\n");
4604     ok(!DeleteFileA("bur"), "File not moved\n");
4605     ok(DeleteFileA("bird"), "File moved\n");
4606
4607     DeleteFile("msitest\\augustus");
4608     RemoveDirectory("msitest");
4609     DeleteFile(msifile);
4610 }
4611
4612 static void test_missingcab(void)
4613 {
4614     UINT r;
4615
4616     CreateDirectoryA("msitest", NULL);
4617     create_file("msitest\\augustus", 500);
4618     create_file("maximus", 500);
4619
4620     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
4621
4622     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4623
4624     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4625
4626     create_pf("msitest", FALSE);
4627     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4628
4629     r = MsiInstallProductA(msifile, NULL);
4630     ok(r == ERROR_SUCCESS ||
4631        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
4632        "Expected ERROR_SUCCESS, got %u\n", r);
4633     if (r == ERROR_SUCCESS)
4634     {
4635       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4636       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4637     }
4638     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4639     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
4640     ok(delete_pf("msitest", FALSE), "File not installed\n");
4641
4642     create_pf("msitest", FALSE);
4643     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4644     create_pf("msitest\\gaius", TRUE);
4645
4646     r = MsiInstallProductA(msifile, "GAIUS=1");
4647     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4648     todo_wine
4649     {
4650         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
4651         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4652     }
4653     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
4654     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
4655     ok(delete_pf("msitest", FALSE), "File not installed\n");
4656
4657     DeleteFile("msitest\\augustus");
4658     RemoveDirectory("msitest");
4659     DeleteFile("maximus");
4660     DeleteFile("test1.cab");
4661     DeleteFile(msifile);
4662 }
4663
4664 static void test_duplicatefiles(void)
4665 {
4666     UINT r;
4667
4668     CreateDirectoryA("msitest", NULL);
4669     create_file("msitest\\maximus", 500);
4670     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4671
4672     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4673
4674     /* fails if the destination folder is not a valid property */
4675
4676     r = MsiInstallProductA(msifile, NULL);
4677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4678     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4679     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4680     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4681     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
4682     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
4683     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
4684     ok(delete_pf("msitest", FALSE), "File not installed\n");
4685
4686     DeleteFile("msitest\\maximus");
4687     RemoveDirectory("msitest");
4688     DeleteFile(msifile);
4689 }
4690
4691 static void test_writeregistryvalues(void)
4692 {
4693     UINT r;
4694     LONG res;
4695     HKEY hkey;
4696     DWORD type, size;
4697     CHAR path[MAX_PATH];
4698
4699     CreateDirectoryA("msitest", NULL);
4700     create_file("msitest\\augustus", 500);
4701
4702     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4703
4704     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4705
4706     r = MsiInstallProductA(msifile, NULL);
4707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4708     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4709     ok(delete_pf("msitest", FALSE), "File installed\n");
4710
4711     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
4712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4713
4714     size = MAX_PATH;
4715     type = REG_MULTI_SZ;
4716     memset(path, 'a', MAX_PATH);
4717     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4719     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4720     ok(size == 15, "Expected 15, got %d\n", size);
4721     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4722
4723     DeleteFile(msifile);
4724     DeleteFile("msitest\\augustus");
4725     RemoveDirectory("msitest");
4726
4727     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
4728     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
4729 }
4730
4731 static void test_sourcefolder(void)
4732 {
4733     UINT r;
4734
4735     CreateDirectoryA("msitest", NULL);
4736     create_file("augustus", 500);
4737
4738     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
4739
4740     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4741
4742     r = MsiInstallProductA(msifile, NULL);
4743     ok(r == ERROR_INSTALL_FAILURE,
4744        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4745     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4746     todo_wine
4747     {
4748         ok(!delete_pf("msitest", FALSE), "File installed\n");
4749     }
4750
4751     RemoveDirectoryA("msitest");
4752
4753     r = MsiInstallProductA(msifile, NULL);
4754     ok(r == ERROR_INSTALL_FAILURE,
4755        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4756     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4757     todo_wine
4758     {
4759         ok(!delete_pf("msitest", FALSE), "File installed\n");
4760     }
4761
4762     DeleteFile(msifile);
4763     DeleteFile("augustus");
4764 }
4765
4766 static void test_customaction51(void)
4767 {
4768     UINT r;
4769
4770     CreateDirectoryA("msitest", NULL);
4771     create_file("msitest\\augustus", 500);
4772
4773     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
4774
4775     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4776
4777     r = MsiInstallProductA(msifile, NULL);
4778     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4779     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4780     ok(delete_pf("msitest", FALSE), "File installed\n");
4781
4782     DeleteFile(msifile);
4783     DeleteFile("msitest\\augustus");
4784     RemoveDirectory("msitest");
4785 }
4786
4787 static void test_installstate(void)
4788 {
4789     UINT r;
4790
4791     CreateDirectoryA("msitest", NULL);
4792     create_file("msitest\\alpha", 500);
4793     create_file("msitest\\beta", 500);
4794     create_file("msitest\\gamma", 500);
4795     create_file("msitest\\theta", 500);
4796     create_file("msitest\\delta", 500);
4797     create_file("msitest\\epsilon", 500);
4798     create_file("msitest\\zeta", 500);
4799     create_file("msitest\\iota", 500);
4800     create_file("msitest\\eta", 500);
4801     create_file("msitest\\kappa", 500);
4802     create_file("msitest\\lambda", 500);
4803     create_file("msitest\\mu", 500);
4804
4805     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
4806
4807     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4808
4809     r = MsiInstallProductA(msifile, NULL);
4810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4811     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4812     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4813     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4814     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4815     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4816     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4817     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4818     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4819     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4820     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4821     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4822     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4823     ok(delete_pf("msitest", FALSE), "File not installed\n");
4824
4825     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
4826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4827     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4828     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4829     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4830     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4831     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4832     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
4833     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4834     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4835     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
4836     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4837     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4838     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4839     ok(delete_pf("msitest", FALSE), "File not installed\n");
4840
4841     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
4842     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4843     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4844     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4845     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4846     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4847     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4848     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4849     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4850     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4851     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4852     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4853     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4854     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4855     ok(delete_pf("msitest", FALSE), "File not installed\n");
4856
4857     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
4858     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4859     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
4860     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4861     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4862     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
4863     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4864     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4865     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4866     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4867     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4868     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4869     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4870     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4871     ok(!delete_pf("msitest", FALSE), "File installed\n");
4872
4873     DeleteFile(msifile);
4874     DeleteFile("msitest\\alpha");
4875     DeleteFile("msitest\\beta");
4876     DeleteFile("msitest\\gamma");
4877     DeleteFile("msitest\\theta");
4878     DeleteFile("msitest\\delta");
4879     DeleteFile("msitest\\epsilon");
4880     DeleteFile("msitest\\zeta");
4881     DeleteFile("msitest\\iota");
4882     DeleteFile("msitest\\eta");
4883     DeleteFile("msitest\\kappa");
4884     DeleteFile("msitest\\lambda");
4885     DeleteFile("msitest\\mu");
4886     RemoveDirectory("msitest");
4887 }
4888
4889 struct sourcepathmap
4890 {
4891     BOOL sost; /* shortone\shorttwo */
4892     BOOL solt; /* shortone\longtwo */
4893     BOOL lost; /* longone\shorttwo */
4894     BOOL lolt; /* longone\longtwo */
4895     BOOL soste; /* shortone\shorttwo source exists */
4896     BOOL solte; /* shortone\longtwo source exists */
4897     BOOL loste; /* longone\shorttwo source exists */
4898     BOOL lolte; /* longone\longtwo source exists */
4899     UINT err;
4900     DWORD size;
4901 } spmap[256] =
4902 {
4903     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4904     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4905     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4906     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4907     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4908     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4909     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4910     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4911     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4912     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4913     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4914     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4915     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4916     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4917     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4918     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4919     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4920     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4921     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4922     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4923     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4924     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4925     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4926     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4927     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4928     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4929     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4930     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4931     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4932     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4933     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4934     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4935     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4936     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4937     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4938     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4939     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4940     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4941     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4942     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4943     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4944     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4945     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4946     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4947     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4948     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4949     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4950     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4951     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4952     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4953     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4954     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4955     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4956     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4957     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4958     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4959     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4960     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4961     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4962     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4963     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4964     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4965     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4966     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4967     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4968     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4969     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4970     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4971     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4972     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4973     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4974     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4975     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
4976     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4977     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
4978     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4979     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
4980     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4981     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
4982     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4983     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4984     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4985     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4986     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4987     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4988     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4989     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4990     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4991     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4992     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4993     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4994     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4995     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
4996     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
4997     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
4998     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
4999     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5000     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5001     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5002     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5003     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5004     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5005     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5006     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5007     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5008     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5009     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5010     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5011     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5012     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5013     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5014     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5015     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5016     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5017     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5018     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5019     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5020     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5021     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5022     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5023     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5024     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5025     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5026     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5027     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5028     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5029     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5030     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5031     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5032     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5033     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5034     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5035     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5036     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5037     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5038     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5039     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5040     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5041     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5042     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5043     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5044     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5045     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5046     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5047     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5048     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5049     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5050     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5051     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5052     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5053     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5054     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5055     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5056     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5057     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5058     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5059     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5060     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5061     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5062     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5063     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5064     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5065     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5066     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5067     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5068     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5069     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5070     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5071     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5072     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5073     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5074     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5075     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5076     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5077     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5078     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5079     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5080     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5081     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5082     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5083     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5084     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5085     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5086     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5087     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5088     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5089     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5090     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5091     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5092     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5093     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5094     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5095     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5096     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5097     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5098     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5099     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5100     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5101     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5102     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5103     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5104     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5105     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5106     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5107     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5108     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5109     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5110     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5111     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5112     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5113     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5114     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5115     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5116     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5117     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5118     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5119     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5120     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5121     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5122     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5123     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5124     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5125     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5126     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5127     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5128     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5129     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5130     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5131     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5132     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5133     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5134     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5135     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5136     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5137     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5138     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5139     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5140     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5141     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5142     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5143     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5144     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5145     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5146     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5147     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5148     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5149     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5150     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5151     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5152     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5153     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5154     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5155     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5156     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5157     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5158     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5159 };
5160
5161 static DWORD get_pf_file_size(LPCSTR file)
5162 {
5163     CHAR path[MAX_PATH];
5164     HANDLE hfile;
5165     DWORD size;
5166
5167     lstrcpyA(path, PROG_FILES_DIR);
5168     lstrcatA(path, "\\");
5169     lstrcatA(path, file);
5170
5171     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
5172     if (hfile == INVALID_HANDLE_VALUE)
5173         return 0;
5174
5175     size = GetFileSize(hfile, NULL);
5176     CloseHandle(hfile);
5177     return size;
5178 }
5179
5180 static void test_sourcepath(void)
5181 {
5182     UINT r, i;
5183
5184     if (!winetest_interactive)
5185     {
5186         skip("Run in interactive mode to run source path tests.\n");
5187         return;
5188     }
5189
5190     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
5191
5192     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5193
5194     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
5195     {
5196         if (spmap[i].sost)
5197         {
5198             CreateDirectoryA("shortone", NULL);
5199             CreateDirectoryA("shortone\\shorttwo", NULL);
5200         }
5201
5202         if (spmap[i].solt)
5203         {
5204             CreateDirectoryA("shortone", NULL);
5205             CreateDirectoryA("shortone\\longtwo", NULL);
5206         }
5207
5208         if (spmap[i].lost)
5209         {
5210             CreateDirectoryA("longone", NULL);
5211             CreateDirectoryA("longone\\shorttwo", NULL);
5212         }
5213
5214         if (spmap[i].lolt)
5215         {
5216             CreateDirectoryA("longone", NULL);
5217             CreateDirectoryA("longone\\longtwo", NULL);
5218         }
5219
5220         if (spmap[i].soste)
5221             create_file("shortone\\shorttwo\\augustus", 50);
5222         if (spmap[i].solte)
5223             create_file("shortone\\longtwo\\augustus", 100);
5224         if (spmap[i].loste)
5225             create_file("longone\\shorttwo\\augustus", 150);
5226         if (spmap[i].lolte)
5227             create_file("longone\\longtwo\\augustus", 200);
5228
5229         r = MsiInstallProductA(msifile, NULL);
5230         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
5231         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
5232            "%d: Expected %d, got %d\n", i, spmap[i].size,
5233            get_pf_file_size("msitest\\augustus"));
5234
5235         if (r == ERROR_SUCCESS)
5236         {
5237             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
5238             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
5239         }
5240         else
5241         {
5242             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
5243             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
5244         }
5245
5246         DeleteFileA("shortone\\shorttwo\\augustus");
5247         DeleteFileA("shortone\\longtwo\\augustus");
5248         DeleteFileA("longone\\shorttwo\\augustus");
5249         DeleteFileA("longone\\longtwo\\augustus");
5250         RemoveDirectoryA("shortone\\shorttwo");
5251         RemoveDirectoryA("shortone\\longtwo");
5252         RemoveDirectoryA("longone\\shorttwo");
5253         RemoveDirectoryA("longone\\longtwo");
5254         RemoveDirectoryA("shortone");
5255         RemoveDirectoryA("longone");
5256     }
5257
5258     DeleteFileA(msifile);
5259 }
5260
5261 static void test_MsiConfigureProductEx(void)
5262 {
5263     UINT r;
5264     LONG res;
5265     DWORD type, size;
5266     HKEY props, source;
5267     CHAR keypath[MAX_PATH * 2];
5268     CHAR localpack[MAX_PATH];
5269
5270     if (on_win9x)
5271     {
5272         win_skip("Different registry keys on Win9x and WinMe\n");
5273         return;
5274     }
5275
5276     CreateDirectoryA("msitest", NULL);
5277     create_file("msitest\\hydrogen", 500);
5278     create_file("msitest\\helium", 500);
5279     create_file("msitest\\lithium", 500);
5280
5281     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5282
5283     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5284
5285     /* NULL szProduct */
5286     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
5287                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5288     ok(r == ERROR_INVALID_PARAMETER,
5289        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5290
5291     /* empty szProduct */
5292     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
5293                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5294     ok(r == ERROR_INVALID_PARAMETER,
5295        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5296
5297     /* garbage szProduct */
5298     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
5299                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
5300     ok(r == ERROR_INVALID_PARAMETER,
5301        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5302
5303     /* guid without brackets */
5304     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
5305                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5306                                "PROPVAR=42");
5307     ok(r == ERROR_INVALID_PARAMETER,
5308        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5309
5310     /* guid with brackets */
5311     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
5312                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5313                                "PROPVAR=42");
5314     ok(r == ERROR_UNKNOWN_PRODUCT,
5315        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5316
5317     /* same length as guid, but random */
5318     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
5319                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5320                                "PROPVAR=42");
5321     ok(r == ERROR_UNKNOWN_PRODUCT,
5322        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5323
5324     /* product not installed yet */
5325     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5326                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5327                                "PROPVAR=42");
5328     ok(r == ERROR_UNKNOWN_PRODUCT,
5329        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5330
5331     /* install the product, per-user unmanaged */
5332     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
5333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5334     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5335     ok(pf_exists("msitest\\helium"), "File not installed\n");
5336     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5337     ok(pf_exists("msitest"), "File not installed\n");
5338
5339     /* product is installed per-user managed, remove it */
5340     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5341                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5342                                "PROPVAR=42");
5343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5344     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5345     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5346     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5347     todo_wine
5348     {
5349         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5350     }
5351
5352     /* product has been removed */
5353     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5354                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5355                                "PROPVAR=42");
5356     ok(r == ERROR_UNKNOWN_PRODUCT,
5357        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
5358
5359     /* install the product, machine */
5360     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5361     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5362     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5363     ok(pf_exists("msitest\\helium"), "File not installed\n");
5364     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5365     ok(pf_exists("msitest"), "File not installed\n");
5366
5367     /* product is installed machine, remove it */
5368     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5369                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5370                                "PROPVAR=42");
5371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5372     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5373     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5374     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5375     todo_wine
5376     {
5377         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5378     }
5379
5380     /* product has been removed */
5381     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5382                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
5383                                "PROPVAR=42");
5384     ok(r == ERROR_UNKNOWN_PRODUCT,
5385        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
5386
5387     /* install the product, machine */
5388     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5390     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5391     ok(pf_exists("msitest\\helium"), "File not installed\n");
5392     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5393     ok(pf_exists("msitest"), "File not installed\n");
5394
5395     DeleteFileA(msifile);
5396
5397     /* local msifile is removed */
5398     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5399                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5400                                "PROPVAR=42");
5401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5402     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5403     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5404     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5405     todo_wine
5406     {
5407         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5408     }
5409
5410     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5411
5412     /* install the product, machine */
5413     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5414     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5415     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5416     ok(pf_exists("msitest\\helium"), "File not installed\n");
5417     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5418     ok(pf_exists("msitest"), "File not installed\n");
5419
5420     DeleteFileA(msifile);
5421
5422     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
5423     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
5424     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
5425
5426     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5428
5429     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
5430                          (const BYTE *)"C:\\idontexist.msi", 18);
5431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5432
5433     /* LocalPackage is used to find the cached msi package */
5434     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5435                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5436                                "PROPVAR=42");
5437     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
5438        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
5439     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5440     ok(pf_exists("msitest\\helium"), "File not installed\n");
5441     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5442     ok(pf_exists("msitest"), "File not installed\n");
5443
5444     RegCloseKey(props);
5445     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
5446
5447     /* LastUsedSource (local msi package) can be used as a last resort */
5448     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5449                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5450                                "PROPVAR=42");
5451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5452     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5453     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5454     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5455     todo_wine
5456     {
5457         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5458     }
5459
5460     /* install the product, machine */
5461     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
5462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5463     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5464     ok(pf_exists("msitest\\helium"), "File not installed\n");
5465     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5466     ok(pf_exists("msitest"), "File not installed\n");
5467
5468     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
5469     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
5470     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
5471
5472     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5474
5475     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
5476                          (const BYTE *)"C:\\idontexist.msi", 18);
5477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5478
5479     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
5480     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
5481
5482     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
5483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5484
5485     type = REG_SZ;
5486     size = MAX_PATH;
5487     res = RegQueryValueExA(source, "PackageName", NULL, &type,
5488                            (LPBYTE)localpack, &size);
5489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5490
5491     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
5492                          (const BYTE *)"idontexist.msi", 15);
5493     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5494
5495     /* SourceList is altered */
5496     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5497                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5498                                "PROPVAR=42");
5499     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
5500        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
5501     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5502     ok(pf_exists("msitest\\helium"), "File not installed\n");
5503     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5504     ok(pf_exists("msitest"), "File not installed\n");
5505
5506     /* restore the SourceList */
5507     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
5508                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
5509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5510
5511     /* finally remove the product */
5512     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
5513                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
5514                                "PROPVAR=42");
5515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5516     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5517     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5518     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5519     todo_wine
5520     {
5521         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5522     }
5523
5524     DeleteFileA(msifile);
5525     RegCloseKey(source);
5526     RegCloseKey(props);
5527     DeleteFileA("msitest\\hydrogen");
5528     DeleteFileA("msitest\\helium");
5529     DeleteFileA("msitest\\lithium");
5530     RemoveDirectoryA("msitest");
5531 }
5532
5533 static void test_missingcomponent(void)
5534 {
5535     UINT r;
5536
5537     CreateDirectoryA("msitest", NULL);
5538     create_file("msitest\\hydrogen", 500);
5539     create_file("msitest\\helium", 500);
5540     create_file("msitest\\lithium", 500);
5541     create_file("beryllium", 500);
5542
5543     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
5544
5545     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5546
5547     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
5548     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5549     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5550     ok(pf_exists("msitest\\helium"), "File not installed\n");
5551     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5552     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5553     ok(pf_exists("msitest"), "File not installed\n");
5554
5555     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
5556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5557     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
5558     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
5559     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
5560     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
5561     todo_wine
5562     {
5563         ok(!delete_pf("msitest", FALSE), "File not removed\n");
5564     }
5565
5566     DeleteFileA(msifile);
5567     DeleteFileA("msitest\\hydrogen");
5568     DeleteFileA("msitest\\helium");
5569     DeleteFileA("msitest\\lithium");
5570     DeleteFileA("beryllium");
5571     RemoveDirectoryA("msitest");
5572 }
5573
5574 static void test_sourcedirprop(void)
5575 {
5576     UINT r;
5577     CHAR props[MAX_PATH];
5578
5579     CreateDirectoryA("msitest", NULL);
5580     create_file("msitest\\augustus", 500);
5581
5582     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
5583
5584     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5585
5586     r = MsiInstallProductA(msifile, NULL);
5587     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5588     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5589     ok(delete_pf("msitest", FALSE), "File installed\n");
5590
5591     DeleteFile("msitest\\augustus");
5592     RemoveDirectory("msitest");
5593
5594     CreateDirectoryA("altsource", NULL);
5595     CreateDirectoryA("altsource\\msitest", NULL);
5596     create_file("altsource\\msitest\\augustus", 500);
5597
5598     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
5599
5600     r = MsiInstallProductA(msifile, props);
5601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5602     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5603     ok(delete_pf("msitest", FALSE), "File installed\n");
5604
5605     DeleteFile(msifile);
5606     DeleteFile("altsource\\msitest\\augustus");
5607     RemoveDirectory("altsource\\msitest");
5608     RemoveDirectory("altsource");
5609 }
5610
5611 static void test_adminimage(void)
5612 {
5613     UINT r;
5614
5615     CreateDirectoryA("msitest", NULL);
5616     CreateDirectoryA("msitest\\first", NULL);
5617     CreateDirectoryA("msitest\\second", NULL);
5618     CreateDirectoryA("msitest\\cabout", NULL);
5619     CreateDirectoryA("msitest\\cabout\\new", NULL);
5620     create_file("msitest\\one.txt", 100);
5621     create_file("msitest\\first\\two.txt", 100);
5622     create_file("msitest\\second\\three.txt", 100);
5623     create_file("msitest\\cabout\\four.txt", 100);
5624     create_file("msitest\\cabout\\new\\five.txt", 100);
5625     create_file("msitest\\filename", 100);
5626     create_file("msitest\\service.exe", 100);
5627
5628     create_database_wordcount(msifile, ai_tables,
5629                               sizeof(ai_tables) / sizeof(msi_table),
5630                               msidbSumInfoSourceTypeAdminImage);
5631
5632     r = MsiInstallProductA(msifile, NULL);
5633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5634
5635     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5636     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
5637     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5638     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
5639     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5640     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
5641     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5642     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
5643     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5644     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5645     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5646     ok(delete_pf("msitest", FALSE), "File not installed\n");
5647
5648     DeleteFileA("msitest.msi");
5649     DeleteFileA("msitest\\cabout\\new\\five.txt");
5650     DeleteFileA("msitest\\cabout\\four.txt");
5651     DeleteFileA("msitest\\second\\three.txt");
5652     DeleteFileA("msitest\\first\\two.txt");
5653     DeleteFileA("msitest\\one.txt");
5654     DeleteFileA("msitest\\service.exe");
5655     DeleteFileA("msitest\\filename");
5656     RemoveDirectoryA("msitest\\cabout\\new");
5657     RemoveDirectoryA("msitest\\cabout");
5658     RemoveDirectoryA("msitest\\second");
5659     RemoveDirectoryA("msitest\\first");
5660     RemoveDirectoryA("msitest");
5661 }
5662
5663 static void test_propcase(void)
5664 {
5665     UINT r;
5666
5667     CreateDirectoryA("msitest", NULL);
5668     create_file("msitest\\augustus", 500);
5669
5670     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
5671
5672     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5673
5674     r = MsiInstallProductA(msifile, "MyProp=42");
5675     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5676     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5677     ok(delete_pf("msitest", FALSE), "File not installed\n");
5678
5679     DeleteFile(msifile);
5680     DeleteFile("msitest\\augustus");
5681     RemoveDirectory("msitest");
5682 }
5683
5684 START_TEST(install)
5685 {
5686     DWORD len;
5687     char temp_path[MAX_PATH], prev_path[MAX_PATH];
5688     STATEMGRSTATUS status;
5689     BOOL ret = FALSE;
5690
5691     init_functionpointers();
5692
5693     on_win9x = check_win9x();
5694
5695     GetCurrentDirectoryA(MAX_PATH, prev_path);
5696     GetTempPath(MAX_PATH, temp_path);
5697     SetCurrentDirectoryA(temp_path);
5698
5699     lstrcpyA(CURR_DIR, temp_path);
5700     len = lstrlenA(CURR_DIR);
5701
5702     if(len && (CURR_DIR[len - 1] == '\\'))
5703         CURR_DIR[len - 1] = 0;
5704
5705     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
5706
5707     /* Create a restore point ourselves so we circumvent the multitude of restore points
5708      * that would have been created by all the installation and removal tests.
5709      */
5710     if (pSRSetRestorePointA)
5711     {
5712         memset(&status, 0, sizeof(status));
5713         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
5714     }
5715
5716     /* Create only one log file and don't append. We have to pass something
5717      * for the log mode for this to work.
5718      */
5719     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, "msitest.log", 0);
5720
5721     test_MsiInstallProduct();
5722     test_MsiSetComponentState();
5723     test_packagecoltypes();
5724     test_continuouscabs();
5725     test_caborder();
5726     test_mixedmedia();
5727     test_samesequence();
5728     test_uiLevelFlags();
5729     test_readonlyfile();
5730     test_setdirproperty();
5731     test_cabisextracted();
5732     test_concurrentinstall();
5733     test_setpropertyfolder();
5734     test_publish_registerproduct();
5735     test_publish_publishproduct();
5736     test_publish_publishfeatures();
5737     test_publish_registeruser();
5738     test_publish_processcomponents();
5739     test_publish();
5740     test_publishsourcelist();
5741     test_transformprop();
5742     test_currentworkingdir();
5743     test_admin();
5744     test_adminprops();
5745     test_removefiles();
5746     test_movefiles();
5747     test_missingcab();
5748     test_duplicatefiles();
5749     test_writeregistryvalues();
5750     test_sourcefolder();
5751     test_customaction51();
5752     test_installstate();
5753     test_sourcepath();
5754     test_MsiConfigureProductEx();
5755     test_missingcomponent();
5756     test_sourcedirprop();
5757     test_adminimage();
5758     test_propcase();
5759
5760     DeleteFileA("msitest.log");
5761
5762     if (pSRSetRestorePointA && ret)
5763     {
5764         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
5765         if (ret)
5766             remove_restore_point(status.llSequenceNumber);
5767     }
5768     FreeLibrary(hsrclient);
5769
5770     SetCurrentDirectoryA(prev_path);
5771 }