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