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