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