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