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