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