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