hlink/tests: Add a trailing '\n' to an ok() call.
[wine] / dlls / msi / tests / install.c
1 /*
2  * Copyright (C) 2006 James Hawkins
3  *
4  * A test program for installing MSI products.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22 #define COBJMACROS
23
24 #include <stdio.h>
25
26 #include <windows.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <msi.h>
30 #include <fci.h>
31 #include <objidl.h>
32 #include <srrestoreptapi.h>
33
34 #include "wine/test.h"
35
36 static UINT (WINAPI *pMsiQueryComponentStateA)
37     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
38 static UINT (WINAPI *pMsiSetExternalUIRecord)
39     (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
40 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiSourceListGetInfoA)
43     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
44
45 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
46
47 static HMODULE hsrclient = 0;
48 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
49 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
50
51 static BOOL on_win9x = FALSE;
52
53 static const char *msifile = "msitest.msi";
54 static const char *msifile2 = "winetest2.msi";
55 static const char *mstfile = "winetest.mst";
56 static CHAR CURR_DIR[MAX_PATH];
57 static CHAR PROG_FILES_DIR[MAX_PATH];
58 static CHAR COMMON_FILES_DIR[MAX_PATH];
59
60 /* msi database data */
61
62 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
63                                     "s72\tS38\ts72\ti2\tS255\tS72\n"
64                                     "Component\tComponent\n"
65                                     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
66                                     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
67                                     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
68                                     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
69                                     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
70                                     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
71                                     "component\t\tMSITESTDIR\t0\t1\tfile\n"
72                                     "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
73
74 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
75                                     "s72\tS72\tl255\n"
76                                     "Directory\tDirectory\n"
77                                     "CABOUTDIR\tMSITESTDIR\tcabout\n"
78                                     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
79                                     "FIRSTDIR\tMSITESTDIR\tfirst\n"
80                                     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
81                                     "NEWDIR\tCABOUTDIR\tnew\n"
82                                     "ProgramFilesFolder\tTARGETDIR\t.\n"
83                                     "TARGETDIR\t\tSourceDir";
84
85 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
86                                   "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
87                                   "Feature\tFeature\n"
88                                   "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
89                                   "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
90                                   "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
91                                   "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
92                                   "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
93                                   "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
94                                   "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
95
96 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
97                                        "s38\ts72\n"
98                                        "FeatureComponents\tFeature_\tComponent_\n"
99                                        "Five\tFive\n"
100                                        "Four\tFour\n"
101                                        "One\tOne\n"
102                                        "Three\tThree\n"
103                                        "Two\tTwo\n"
104                                        "feature\tcomponent\n"
105                                        "service_feature\tservice_comp\n";
106
107 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
108                                "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
109                                "File\tFile\n"
110                                "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
111                                "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
112                                "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
113                                "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
114                                "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
115                                "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
116                                "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
117
118 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
119                                            "s72\tS255\tI2\n"
120                                            "InstallExecuteSequence\tAction\n"
121                                            "AllocateRegistrySpace\tNOT Installed\t1550\n"
122                                            "CostFinalize\t\t1000\n"
123                                            "CostInitialize\t\t800\n"
124                                            "FileCost\t\t900\n"
125                                            "ResolveSource\t\t950\n"
126                                            "MoveFiles\t\t1700\n"
127                                            "InstallFiles\t\t4000\n"
128                                            "DuplicateFiles\t\t4500\n"
129                                            "WriteEnvironmentStrings\t\t4550\n"
130                                            "CreateShortcuts\t\t4600\n"
131                                            "InstallServices\t\t5000\n"
132                                            "InstallFinalize\t\t6600\n"
133                                            "InstallInitialize\t\t1500\n"
134                                            "InstallValidate\t\t1400\n"
135                                            "LaunchConditions\t\t100\n"
136                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
137
138 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
139                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
140                                 "Media\tDiskId\n"
141                                 "1\t3\t\t\tDISK1\t\n"
142                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
143
144 static const CHAR property_dat[] = "Property\tValue\n"
145                                    "s72\tl0\n"
146                                    "Property\tProperty\n"
147                                    "DefaultUIFont\tDlgFont8\n"
148                                    "HASUIRUN\t0\n"
149                                    "INSTALLLEVEL\t3\n"
150                                    "InstallMode\tTypical\n"
151                                    "Manufacturer\tWine\n"
152                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
153                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
154                                    "ProductID\tnone\n"
155                                    "ProductLanguage\t1033\n"
156                                    "ProductName\tMSITEST\n"
157                                    "ProductVersion\t1.1.1\n"
158                                    "PROMPTROLLBACKCOST\tP\n"
159                                    "Setup\tSetup\n"
160                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
161                                    "AdminProperties\tPOSTADMIN\n"
162                                    "ROOTDRIVE\tC:\\\n"
163                                    "SERVNAME\tTestService\n"
164                                    "SERVDISP\tTestServiceDisp\n";
165
166 static const CHAR aup_property_dat[] = "Property\tValue\n"
167                                        "s72\tl0\n"
168                                        "Property\tProperty\n"
169                                        "DefaultUIFont\tDlgFont8\n"
170                                        "HASUIRUN\t0\n"
171                                        "ALLUSERS\t1\n"
172                                        "INSTALLLEVEL\t3\n"
173                                        "InstallMode\tTypical\n"
174                                        "Manufacturer\tWine\n"
175                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
176                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
177                                        "ProductID\tnone\n"
178                                        "ProductLanguage\t1033\n"
179                                        "ProductName\tMSITEST\n"
180                                        "ProductVersion\t1.1.1\n"
181                                        "PROMPTROLLBACKCOST\tP\n"
182                                        "Setup\tSetup\n"
183                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
184                                        "AdminProperties\tPOSTADMIN\n"
185                                        "ROOTDRIVE\tC:\\\n"
186                                        "SERVNAME\tTestService\n"
187                                        "SERVDISP\tTestServiceDisp\n";
188
189 static const CHAR aup2_property_dat[] = "Property\tValue\n"
190                                         "s72\tl0\n"
191                                         "Property\tProperty\n"
192                                         "DefaultUIFont\tDlgFont8\n"
193                                         "HASUIRUN\t0\n"
194                                         "ALLUSERS\t2\n"
195                                         "INSTALLLEVEL\t3\n"
196                                         "InstallMode\tTypical\n"
197                                         "Manufacturer\tWine\n"
198                                         "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
199                                         "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
200                                         "ProductID\tnone\n"
201                                         "ProductLanguage\t1033\n"
202                                         "ProductName\tMSITEST\n"
203                                         "ProductVersion\t1.1.1\n"
204                                         "PROMPTROLLBACKCOST\tP\n"
205                                         "Setup\tSetup\n"
206                                         "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
207                                         "AdminProperties\tPOSTADMIN\n"
208                                         "ROOTDRIVE\tC:\\\n"
209                                         "SERVNAME\tTestService\n"
210                                         "SERVDISP\tTestServiceDisp\n";
211
212 static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
213                                    "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
214                                    "Shortcut\tShortcut\n"
215                                    "Shortcut\tMSITESTDIR\tShortcut\tcomponent\tShortcut\t\tShortcut\t\t\t\t\t\n";
216
217 static const CHAR environment_dat[] = "Environment\tName\tValue\tComponent_\n"
218                                       "s72\tl255\tL255\ts72\n"
219                                       "Environment\tEnvironment\n"
220                                       "Var1\t=-MSITESTVAR1\t1\tOne\n"
221                                       "Var2\tMSITESTVAR2\t1\tOne\n"
222                                       "Var3\t=-MSITESTVAR3\t1\tOne\n"
223                                       "Var4\tMSITESTVAR4\t1\tOne\n"
224                                       "Var5\t-MSITESTVAR5\t\tOne\n"
225                                       "Var6\tMSITESTVAR6\t\tOne\n"
226                                       "Var7\t!-MSITESTVAR7\t\tOne\n"
227                                       "Var8\t!-*MSITESTVAR8\t\tOne\n"
228                                       "Var9\t=-MSITESTVAR9\t\tOne\n"
229                                       "Var10\t=MSITESTVAR10\t\tOne\n"
230                                       "Var11\t+-MSITESTVAR11\t[~];1\tOne\n"
231                                       "Var12\t+-MSITESTVAR11\t[~];2\tOne\n"
232                                       "Var13\t+-MSITESTVAR12\t[~];1\tOne\n"
233                                       "Var14\t=MSITESTVAR13\t[~];1\tOne\n"
234                                       "Var15\t=MSITESTVAR13\t[~];2\tOne\n"
235                                       "Var16\t=MSITESTVAR14\t;1;\tOne\n"
236                                       "Var17\t=MSITESTVAR15\t;;1;;\tOne\n"
237                                       "Var18\t=MSITESTVAR16\t 1 \tOne\n"
238                                       "Var19\t+-MSITESTVAR17\t1\tOne\n"
239                                       "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n"
240                                       "Var21\t+-MSITESTVAR18\t1\tOne\n"
241                                       "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n"
242                                       "Var23\t+-MSITESTVAR19\t1\tOne\n"
243                                       "Var24\t+-MSITESTVAR19\t[~]2\tOne\n"
244                                       "Var25\t+-MSITESTVAR20\t1\tOne\n"
245                                       "Var26\t+-MSITESTVAR20\t2[~]\tOne\n";
246
247 /* Expected results, starting from MSITESTVAR11 onwards */
248 static const CHAR *environment_dat_results[] = {"1;2",    /*MSITESTVAR11*/
249                                                 "1",      /*MSITESTVAR12*/
250                                                 "1;2",    /*MSITESTVAR13*/
251                                                 ";1;",    /*MSITESTVAR14*/
252                                                 ";;1;;",  /*MSITESTVAR15*/
253                                                 " 1 ",    /*MSITESTVAR16*/
254                                                 ";;2;;1", /*MSITESTVAR17*/
255                                                 "1;;2;;", /*MSITESTVAR18*/
256                                                 "1",      /*MSITESTVAR19*/
257                                                 "1",      /*MSITESTVAR20*/
258                                                 NULL};
259
260 static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n"
261                                     "s38\ti2\tS255\n"
262                                     "Condition\tFeature_\tLevel\n"
263                                     "One\t4\t1\n";
264
265 static const CHAR up_property_dat[] = "Property\tValue\n"
266                                       "s72\tl0\n"
267                                       "Property\tProperty\n"
268                                       "DefaultUIFont\tDlgFont8\n"
269                                       "HASUIRUN\t0\n"
270                                       "INSTALLLEVEL\t3\n"
271                                       "InstallMode\tTypical\n"
272                                       "Manufacturer\tWine\n"
273                                       "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
274                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
275                                       "ProductID\tnone\n"
276                                       "ProductLanguage\t1033\n"
277                                       "ProductName\tMSITEST\n"
278                                       "ProductVersion\t1.1.1\n"
279                                       "PROMPTROLLBACKCOST\tP\n"
280                                       "Setup\tSetup\n"
281                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
282                                       "AdminProperties\tPOSTADMIN\n"
283                                       "ROOTDRIVE\tC:\\\n"
284                                       "SERVNAME\tTestService\n"
285                                       "SERVDISP\tTestServiceDisp\n"
286                                       "RemovePreviousVersions\t1\n";
287
288 static const CHAR up2_property_dat[] = "Property\tValue\n"
289                                        "s72\tl0\n"
290                                        "Property\tProperty\n"
291                                        "DefaultUIFont\tDlgFont8\n"
292                                        "HASUIRUN\t0\n"
293                                        "INSTALLLEVEL\t3\n"
294                                        "InstallMode\tTypical\n"
295                                        "Manufacturer\tWine\n"
296                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
297                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
298                                        "ProductID\tnone\n"
299                                        "ProductLanguage\t1033\n"
300                                        "ProductName\tMSITEST\n"
301                                        "ProductVersion\t1.1.2\n"
302                                        "PROMPTROLLBACKCOST\tP\n"
303                                        "Setup\tSetup\n"
304                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
305                                        "AdminProperties\tPOSTADMIN\n"
306                                        "ROOTDRIVE\tC:\\\n"
307                                        "SERVNAME\tTestService\n"
308                                        "SERVDISP\tTestServiceDisp\n";
309
310 static const CHAR up3_property_dat[] = "Property\tValue\n"
311                                        "s72\tl0\n"
312                                        "Property\tProperty\n"
313                                        "DefaultUIFont\tDlgFont8\n"
314                                        "HASUIRUN\t0\n"
315                                        "INSTALLLEVEL\t3\n"
316                                        "InstallMode\tTypical\n"
317                                        "Manufacturer\tWine\n"
318                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
319                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
320                                        "ProductID\tnone\n"
321                                        "ProductLanguage\t1033\n"
322                                        "ProductName\tMSITEST\n"
323                                        "ProductVersion\t1.1.2\n"
324                                        "PROMPTROLLBACKCOST\tP\n"
325                                        "Setup\tSetup\n"
326                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
327                                        "AdminProperties\tPOSTADMIN\n"
328                                        "ROOTDRIVE\tC:\\\n"
329                                        "SERVNAME\tTestService\n"
330                                        "SERVDISP\tTestServiceDisp\n"
331                                        "RemovePreviousVersions\t1\n";
332
333 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
334                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
335                                    "Registry\tRegistry\n"
336                                    "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
337                                    "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
338                                    "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
339                                    "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
340
341 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
342                                           "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
343                                           "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
344                                           "ServiceInstall\tServiceInstall\n"
345                                           "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
346
347 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
348                                           "s72\tl255\ti2\tL255\tI2\ts72\n"
349                                           "ServiceControl\tServiceControl\n"
350                                           "ServiceControl\tTestService\t8\t\t0\tservice_comp";
351
352 static const CHAR sss_service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
353                                               "s72\tl255\ti2\tL255\tI2\ts72\n"
354                                               "ServiceControl\tServiceControl\n"
355                                               "ServiceControl\tSpooler\t1\t\t0\tservice_comp";
356
357 static const CHAR sss_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
358                                                "s72\tS255\tI2\n"
359                                                "InstallExecuteSequence\tAction\n"
360                                                "CostFinalize\t\t1000\n"
361                                                "CostInitialize\t\t800\n"
362                                                "FileCost\t\t900\n"
363                                                "ResolveSource\t\t950\n"
364                                                "MoveFiles\t\t1700\n"
365                                                "InstallFiles\t\t4000\n"
366                                                "DuplicateFiles\t\t4500\n"
367                                                "WriteEnvironmentStrings\t\t4550\n"
368                                                "CreateShortcuts\t\t4600\n"
369                                                "StartServices\t\t5000\n"
370                                                "DeleteServices\t\t5500\n"
371                                                "InstallFinalize\t\t6600\n"
372                                                "InstallInitialize\t\t1500\n"
373                                                "InstallValidate\t\t1400\n"
374                                                "LaunchConditions\t\t100\n";
375
376 /* tables for test_continuouscabs */
377 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
378                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
379                                        "Component\tComponent\n"
380                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
381                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
382                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
383
384 static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
385                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
386                                         "Component\tComponent\n"
387                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
388                                         "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
389                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
390
391 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
392                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
393                                      "Feature\tFeature\n"
394                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
395
396 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
397                                           "s38\ts72\n"
398                                           "FeatureComponents\tFeature_\tComponent_\n"
399                                           "feature\tmaximus\n"
400                                           "feature\taugustus\n"
401                                           "feature\tcaesar";
402
403 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
404                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
405                                   "File\tFile\n"
406                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
407                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
408                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
409
410 static const CHAR cc2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
411                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
412                                    "File\tFile\n"
413                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
414                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
415                                    "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
416                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
417
418 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
419                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
420                                    "Media\tDiskId\n"
421                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
422                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
423                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
424
425 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
426                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
427                                   "File\tFile\n"
428                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
429                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
430                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
431
432 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
433                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
434                                    "Media\tDiskId\n"
435                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
436                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
437                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
438
439 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
440                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
441                                     "Media\tDiskId\n"
442                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
443                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
444                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
445
446 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
447                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
448                                   "File\tFile\n"
449                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
450                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
451                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
452
453 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
454                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
455                                    "Media\tDiskId\n"
456                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
457
458 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
459                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
460                                    "Media\tDiskId\n"
461                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
462                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
463                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
464
465 /* tables for test_uiLevelFlags */
466 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
467                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
468                                        "Component\tComponent\n"
469                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
470                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
471                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
472
473 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
474                                            "s72\tS255\tI2\n"
475                                            "InstallUISequence\tAction\n"
476                                            "SetUIProperty\t\t5\n"
477                                            "ExecuteAction\t\t1100\n";
478
479 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
480                                            "s72\ti2\tS64\tS0\tS255\n"
481                                            "CustomAction\tAction\n"
482                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
483
484 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
485                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
486                                         "Component\tComponent\n"
487                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
488
489 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
490                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
491                                       "Feature\tFeature\n"
492                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
493                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
494
495 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
496                                            "s38\ts72\n"
497                                            "FeatureComponents\tFeature_\tComponent_\n"
498                                            "feature\tmaximus\n"
499                                            "montecristo\tmaximus";
500
501 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
502                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
503                                    "File\tFile\n"
504                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
505
506 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
507                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
508                                     "Media\tDiskId\n"
509                                     "1\t1\t\t\tDISK1\t\n";
510
511 static const CHAR rofc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
512                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
513                                     "File\tFile\n"
514                                     "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1";
515
516 static const CHAR rofc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
517                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
518                                      "Media\tDiskId\n"
519                                      "1\t1\t\ttest1.cab\tDISK1\t\n";
520
521 static const CHAR lus2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
522                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
523                                      "Media\tDiskId\n"
524                                      "1\t1\t\t#test1.cab\tDISK1\t\n";
525
526 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
527                                                "s72\tS255\tI2\n"
528                                                "InstallExecuteSequence\tAction\n"
529                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
530                                                "CostFinalize\t\t1000\n"
531                                                "CostInitialize\t\t800\n"
532                                                "FileCost\t\t900\n"
533                                                "InstallFiles\t\t4000\n"
534                                                "InstallFinalize\t\t6600\n"
535                                                "InstallInitialize\t\t1500\n"
536                                                "InstallValidate\t\t1400\n"
537                                                "LaunchConditions\t\t100\n"
538                                                "SetDirProperty\t\t950";
539
540 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
541                                             "s72\ti2\tS64\tS0\tS255\n"
542                                             "CustomAction\tAction\n"
543                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
544
545 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
546                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
547                                         "Component\tComponent\n"
548                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
549                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
550                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
551                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
552
553 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
554                                            "s38\ts72\n"
555                                            "FeatureComponents\tFeature_\tComponent_\n"
556                                            "feature\tmaximus\n"
557                                            "feature\taugustus\n"
558                                            "feature\tcaesar\n"
559                                            "feature\tgaius";
560
561 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
562                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
563                                    "File\tFile\n"
564                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
565                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
566                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
567                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
568
569 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
570                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
571                                     "Media\tDiskId\n"
572                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
573                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
574                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
575
576 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
577                                               "s72\tS255\tI2\n"
578                                               "InstallExecuteSequence\tAction\n"
579                                               "CostFinalize\t\t1000\n"
580                                               "CostInitialize\t\t800\n"
581                                               "FileCost\t\t900\n"
582                                               "InstallFiles\t\t4000\n"
583                                               "InstallServices\t\t5000\n"
584                                               "InstallFinalize\t\t6600\n"
585                                               "InstallInitialize\t\t1500\n"
586                                               "RunInstall\t\t1600\n"
587                                               "InstallValidate\t\t1400\n"
588                                               "LaunchConditions\t\t100";
589
590 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
591                                             "s72\ti2\tS64\tS0\tS255\n"
592                                             "CustomAction\tAction\n"
593                                             "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
594
595 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
596                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
597                                        "Component\tComponent\n"
598                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
599
600 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
601                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
602                                         "Component\tComponent\n"
603                                         "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
604
605 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
606                                            "s38\ts72\n"
607                                            "FeatureComponents\tFeature_\tComponent_\n"
608                                            "feature\taugustus";
609
610 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
611                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
612                                    "File\tFile\n"
613                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
614
615 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
616                                             "s72\ti2\tS64\tS0\tS255\n"
617                                             "CustomAction\tAction\n"
618                                             "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
619
620 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
621                                                "s72\tS255\tI2\n"
622                                                "InstallExecuteSequence\tAction\n"
623                                                "CostFinalize\t\t1000\n"
624                                                "CostInitialize\t\t800\n"
625                                                "FileCost\t\t900\n"
626                                                "SetFolderProp\t\t950\n"
627                                                "InstallFiles\t\t4000\n"
628                                                "InstallServices\t\t5000\n"
629                                                "InstallFinalize\t\t6600\n"
630                                                "InstallInitialize\t\t1500\n"
631                                                "InstallValidate\t\t1400\n"
632                                                "LaunchConditions\t\t100";
633
634 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
635                                              "s72\tS255\tI2\n"
636                                              "InstallUISequence\tAction\n"
637                                              "CostInitialize\t\t800\n"
638                                              "FileCost\t\t900\n"
639                                              "CostFinalize\t\t1000\n"
640                                              "ExecuteAction\t\t1100\n";
641
642 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
643                                               "s72\tS255\tI2\n"
644                                               "InstallExecuteSequence\tAction\n"
645                                               "ValidateProductID\t\t700\n"
646                                               "CostInitialize\t\t800\n"
647                                               "FileCost\t\t900\n"
648                                               "CostFinalize\t\t1000\n"
649                                               "InstallValidate\t\t1400\n"
650                                               "InstallInitialize\t\t1500\n"
651                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
652                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
653                                               "RemoveFiles\t\t3500\n"
654                                               "InstallFiles\t\t4000\n"
655                                               "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
656                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
657                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
658                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
659                                               "InstallFinalize\t\t6600";
660
661 static const CHAR ppc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
662                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
663                                         "Component\tComponent\n"
664                                         "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n"
665                                         "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n";
666
667 static const CHAR ppc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
668                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
669                                    "File\tFile\n"
670                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n"
671                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t2";
672
673 static const CHAR ppc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
674                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
675                                     "Media\tDiskId\n"
676                                     "1\t2\t\t\tDISK1\t\n";
677
678 static const CHAR ppc_feature_comp_dat[] = "Feature_\tComponent_\n"
679                                            "s38\ts72\n"
680                                            "FeatureComponents\tFeature_\tComponent_\n"
681                                            "feature\tmaximus\n"
682                                            "feature\taugustus\n"
683                                            "montecristo\tmaximus";
684
685 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
686                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
687                                        "Component\tComponent\n"
688                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
689
690 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
691                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
692                                         "Component\tComponent\n"
693                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
694
695 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
696                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
697                                         "Component\tComponent\n"
698                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
699
700 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
701                                             "s72\ti2\tS64\tS0\tS255\n"
702                                             "CustomAction\tAction\n"
703                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
704
705 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
706                                              "s72\tS255\tI2\n"
707                                              "AdminExecuteSequence\tAction\n"
708                                              "CostFinalize\t\t1000\n"
709                                              "CostInitialize\t\t800\n"
710                                              "FileCost\t\t900\n"
711                                              "SetPOSTADMIN\t\t950\n"
712                                              "InstallFiles\t\t4000\n"
713                                              "InstallFinalize\t\t6600\n"
714                                              "InstallInitialize\t\t1500\n"
715                                              "InstallValidate\t\t1400\n"
716                                              "LaunchConditions\t\t100";
717
718 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
719                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
720                                         "Component\tComponent\n"
721                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718 and MyProp=42\taugustus\n";
722
723 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
724                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
725                                         "Component\tComponent\n"
726                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
727                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
728                                         "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
729
730 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
731                                            "s38\ts72\n"
732                                            "FeatureComponents\tFeature_\tComponent_\n"
733                                            "feature\thydrogen\n"
734                                            "feature\thelium\n"
735                                            "feature\tlithium";
736
737 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
738                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
739                                    "File\tFile\n"
740                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
741                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
742                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
743
744 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
745                                                "s72\tS255\tI2\n"
746                                                "InstallExecuteSequence\tAction\n"
747                                                "ValidateProductID\t\t700\n"
748                                                "CostInitialize\t\t800\n"
749                                                "FileCost\t\t900\n"
750                                                "CostFinalize\t\t1000\n"
751                                                "InstallValidate\t\t1400\n"
752                                                "InstallInitialize\t\t1500\n"
753                                                "ProcessComponents\t\t1600\n"
754                                                "UnpublishFeatures\t\t1800\n"
755                                                "RemoveFiles\t\t3500\n"
756                                                "InstallFiles\t\t4000\n"
757                                                "RegisterProduct\t\t6100\n"
758                                                "PublishFeatures\t\t6300\n"
759                                                "PublishProduct\t\t6400\n"
760                                                "InstallFinalize\t\t6600";
761
762 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
763                                            "s72\ts72\tS255\ts72\tI2\n"
764                                            "RemoveFile\tFileKey\n"
765                                            "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
766                                            "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
767                                            "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
768                                            "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
769                                            "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
770                                            "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
771                                            "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
772                                            "block\thelium\tblock\tMSITESTDIR\t3\n"
773                                            "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n"
774                                            "nanoacre\thydrogen\t\tCABOUTDIR\t3\n";
775
776 static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
777                                         "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
778                                         "MoveFile\tFileKey\n"
779                                         "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
780                                         "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
781                                         "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
782                                         "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
783                                         "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
784                                         "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
785                                         "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
786                                         "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
787                                         "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
788                                         "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
789                                         "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
790                                         "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
791                                         "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
792                                         "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n"
793                                         "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
794                                         "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
795                                         "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
796                                         "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
797
798 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
799                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
800                                         "Component\tComponent\n"
801                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
802                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
803                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
804                                         "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
805
806 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
807                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
808                                   "File\tFile\n"
809                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
810                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
811                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
812                                   "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
813
814 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
815                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
816                                    "Media\tDiskId\n"
817                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
818                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
819                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
820                                    "4\t4\t\ttest3.cab\tDISK3\t\n";
821
822 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
823                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
824                                        "MsiFileHash\tFile_\n"
825                                        "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
826
827 static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
828                                        "s72\tS72\tl255\n"
829                                        "Directory\tDirectory\n"
830                                        "THIS\tMSITESTDIR\tthis\n"
831                                        "DOESNOT\tTHIS\tdoesnot\n"
832                                        "NONEXISTENT\tDOESNOT\texist\n"
833                                        "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
834                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
835                                        "TARGETDIR\t\tSourceDir";
836
837 static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
838                                             "s72\ts72\ts72\tS255\tS72\n"
839                                             "DuplicateFile\tFileKey\n"
840                                             "maximus\tmaximus\tmaximus\taugustus\t\n"
841                                             "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n"
842                                             "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n";
843
844 static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
845                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
846                                         "Component\tComponent\n"
847                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
848
849 static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
850                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
851                                        "Registry\tRegistry\n"
852                                        "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
853
854 static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
855                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
856                                          "Component\tComponent\n"
857                                          "augustus\t\tMSITESTDIR\t0\tMYPROP=42\taugustus\n";
858
859 static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
860                                                 "s72\tS255\tI2\n"
861                                                 "InstallExecuteSequence\tAction\n"
862                                                 "ValidateProductID\t\t700\n"
863                                                 "GoodSetProperty\t\t725\n"
864                                                 "BadSetProperty\t\t750\n"
865                                                 "CostInitialize\t\t800\n"
866                                                 "ResolveSource\t\t810\n"
867                                                 "FileCost\t\t900\n"
868                                                 "SetSourceDir\tSRCDIR\t910\n"
869                                                 "CostFinalize\t\t1000\n"
870                                                 "InstallValidate\t\t1400\n"
871                                                 "InstallInitialize\t\t1500\n"
872                                                 "InstallFiles\t\t4000\n"
873                                                 "InstallFinalize\t\t6600";
874
875 static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
876                                              "s72\ti2\tS64\tS0\n"
877                                              "CustomAction\tAction\n"
878                                              "GoodSetProperty\t51\tMYPROP\t42\n"
879                                              "BadSetProperty\t51\t\tMYPROP\n"
880                                              "SetSourceDir\t51\tSourceDir\t[SRCDIR]\n";
881
882 static const CHAR is_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
883                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
884                                      "Feature\tFeature\n"
885                                      "one\t\t\t\t2\t1\t\t0\n" /* favorLocal */
886                                      "two\t\t\t\t2\t1\t\t1\n" /* favorSource */
887                                      "three\t\t\t\t2\t1\t\t4\n" /* favorAdvertise */
888                                      "four\t\t\t\t2\t0\t\t0"; /* disabled */
889
890 static const CHAR is_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
891                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
892                                        "Component\tComponent\n"
893                                        "alpha\t\tMSITESTDIR\t0\t\talpha_file\n" /* favorLocal:Local */
894                                        "beta\t\tMSITESTDIR\t1\t\tbeta_file\n" /* favorLocal:Source */
895                                        "gamma\t\tMSITESTDIR\t2\t\tgamma_file\n" /* favorLocal:Optional */
896                                        "theta\t\tMSITESTDIR\t0\t\ttheta_file\n" /* favorSource:Local */
897                                        "delta\t\tMSITESTDIR\t1\t\tdelta_file\n" /* favorSource:Source */
898                                        "epsilon\t\tMSITESTDIR\t2\t\tepsilon_file\n" /* favorSource:Optional */
899                                        "zeta\t\tMSITESTDIR\t0\t\tzeta_file\n" /* favorAdvertise:Local */
900                                        "iota\t\tMSITESTDIR\t1\t\tiota_file\n" /* favorAdvertise:Source */
901                                        "eta\t\tMSITESTDIR\t2\t\teta_file\n" /* favorAdvertise:Optional */
902                                        "kappa\t\tMSITESTDIR\t0\t\tkappa_file\n" /* disabled:Local */
903                                        "lambda\t\tMSITESTDIR\t1\t\tlambda_file\n" /* disabled:Source */
904                                        "mu\t\tMSITESTDIR\t2\t\tmu_file\n"; /* disabled:Optional */
905
906 static const CHAR is_feature_comp_dat[] = "Feature_\tComponent_\n"
907                                           "s38\ts72\n"
908                                           "FeatureComponents\tFeature_\tComponent_\n"
909                                           "one\talpha\n"
910                                           "one\tbeta\n"
911                                           "one\tgamma\n"
912                                           "two\ttheta\n"
913                                           "two\tdelta\n"
914                                           "two\tepsilon\n"
915                                           "three\tzeta\n"
916                                           "three\tiota\n"
917                                           "three\teta\n"
918                                           "four\tkappa\n"
919                                           "four\tlambda\n"
920                                           "four\tmu";
921
922 static const CHAR is_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
923                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
924                                   "File\tFile\n"
925                                   "alpha_file\talpha\talpha\t500\t\t\t8192\t1\n"
926                                   "beta_file\tbeta\tbeta\t500\t\t\t8291\t2\n"
927                                   "gamma_file\tgamma\tgamma\t500\t\t\t8192\t3\n"
928                                   "theta_file\ttheta\ttheta\t500\t\t\t8192\t4\n"
929                                   "delta_file\tdelta\tdelta\t500\t\t\t8192\t5\n"
930                                   "epsilon_file\tepsilon\tepsilon\t500\t\t\t8192\t6\n"
931                                   "zeta_file\tzeta\tzeta\t500\t\t\t8192\t7\n"
932                                   "iota_file\tiota\tiota\t500\t\t\t8192\t8\n"
933                                   "eta_file\teta\teta\t500\t\t\t8192\t9\n"
934                                   "kappa_file\tkappa\tkappa\t500\t\t\t8192\t10\n"
935                                   "lambda_file\tlambda\tlambda\t500\t\t\t8192\t11\n"
936                                   "mu_file\tmu\tmu\t500\t\t\t8192\t12";
937
938 static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
939                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
940                                    "Media\tDiskId\n"
941                                    "1\t12\t\t\tDISK1\t\n";
942
943 static const CHAR sp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
944                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
945                                         "Component\tComponent\n"
946                                         "augustus\t\tTWODIR\t0\t\taugustus\n";
947
948 static const CHAR sp_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
949                                        "s72\tS72\tl255\n"
950                                        "Directory\tDirectory\n"
951                                        "TARGETDIR\t\tSourceDir\n"
952                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
953                                        "MSITESTDIR\tProgramFilesFolder\tmsitest:.\n"
954                                        "ONEDIR\tMSITESTDIR\t.:shortone|longone\n"
955                                        "TWODIR\tONEDIR\t.:shorttwo|longtwo";
956
957 static const CHAR mcp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
958                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
959                                         "Component\tComponent\n"
960                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
961                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
962                                         "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
963
964 static const CHAR mcp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
965                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
966                                       "Feature\tFeature\n"
967                                       "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
968                                       "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
969                                       "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
970
971 static const CHAR mcp_feature_comp_dat[] = "Feature_\tComponent_\n"
972                                            "s38\ts72\n"
973                                            "FeatureComponents\tFeature_\tComponent_\n"
974                                            "hydroxyl\thydrogen\n"
975                                            "heliox\thelium\n"
976                                            "lithia\tlithium";
977
978 static const CHAR mcomp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
979                                      "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
980                                      "File\tFile\n"
981                                      "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
982                                      "helium\thelium\thelium\t0\t\t\t8192\t1\n"
983                                      "lithium\tlithium\tlithium\t0\t\t\t8192\t1\n"
984                                      "beryllium\tmissingcomp\tberyllium\t0\t\t\t8192\t1";
985
986 static const CHAR ai_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
987                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
988                                   "File\tFile\n"
989                                   "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
990                                   "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
991                                   "one.txt\tOne\tone.txt\t1000\t\t\t16384\t1\n"
992                                   "three.txt\tThree\tthree.txt\t1000\t\t\t16384\t3\n"
993                                   "two.txt\tTwo\ttwo.txt\t1000\t\t\t16384\t2\n"
994                                   "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
995                                   "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
996
997 static const CHAR ip_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
998                                               "s72\tS255\tI2\n"
999                                               "InstallExecuteSequence\tAction\n"
1000                                               "CostFinalize\t\t1000\n"
1001                                               "ValidateProductID\t\t700\n"
1002                                               "CostInitialize\t\t800\n"
1003                                               "FileCost\t\t900\n"
1004                                               "RemoveFiles\t\t3500\n"
1005                                               "InstallFiles\t\t4000\n"
1006                                               "RegisterUser\t\t6000\n"
1007                                               "RegisterProduct\t\t6100\n"
1008                                               "PublishFeatures\t\t6300\n"
1009                                               "PublishProduct\t\t6400\n"
1010                                               "InstallFinalize\t\t6600\n"
1011                                               "InstallInitialize\t\t1500\n"
1012                                               "ProcessComponents\t\t1600\n"
1013                                               "UnpublishFeatures\t\t1800\n"
1014                                               "InstallValidate\t\t1400\n"
1015                                               "LaunchConditions\t\t100\n"
1016                                               "TestInstalledProp\tInstalled AND NOT REMOVE\t950\n";
1017
1018 static const CHAR ip_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1019                                            "s72\ti2\tS64\tS0\tS255\n"
1020                                            "CustomAction\tAction\n"
1021                                            "TestInstalledProp\t19\t\tTest failed\t\n";
1022
1023 static const CHAR aup_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1024                                                "s72\tS255\tI2\n"
1025                                                "InstallExecuteSequence\tAction\n"
1026                                                "CostFinalize\t\t1000\n"
1027                                                "ValidateProductID\t\t700\n"
1028                                                "CostInitialize\t\t800\n"
1029                                                "FileCost\t\t900\n"
1030                                                "RemoveFiles\t\t3500\n"
1031                                                "InstallFiles\t\t4000\n"
1032                                                "RegisterUser\t\t6000\n"
1033                                                "RegisterProduct\t\t6100\n"
1034                                                "PublishFeatures\t\t6300\n"
1035                                                "PublishProduct\t\t6400\n"
1036                                                "InstallFinalize\t\t6600\n"
1037                                                "InstallInitialize\t\t1500\n"
1038                                                "ProcessComponents\t\t1600\n"
1039                                                "UnpublishFeatures\t\t1800\n"
1040                                                "InstallValidate\t\t1400\n"
1041                                                "LaunchConditions\t\t100\n"
1042                                                "TestAllUsersProp\tALLUSERS AND NOT REMOVE\t50\n";
1043
1044 static const CHAR aup2_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1045                                                 "s72\tS255\tI2\n"
1046                                                 "InstallExecuteSequence\tAction\n"
1047                                                 "CostFinalize\t\t1000\n"
1048                                                 "ValidateProductID\t\t700\n"
1049                                                 "CostInitialize\t\t800\n"
1050                                                 "FileCost\t\t900\n"
1051                                                 "RemoveFiles\t\t3500\n"
1052                                                 "InstallFiles\t\t4000\n"
1053                                                 "RegisterUser\t\t6000\n"
1054                                                 "RegisterProduct\t\t6100\n"
1055                                                 "PublishFeatures\t\t6300\n"
1056                                                 "PublishProduct\t\t6400\n"
1057                                                 "InstallFinalize\t\t6600\n"
1058                                                 "InstallInitialize\t\t1500\n"
1059                                                 "ProcessComponents\t\t1600\n"
1060                                                 "UnpublishFeatures\t\t1800\n"
1061                                                 "InstallValidate\t\t1400\n"
1062                                                 "LaunchConditions\t\t100\n"
1063                                                 "TestAllUsersProp\tALLUSERS=2 AND NOT REMOVE\t50\n";
1064
1065 static const CHAR aup3_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1066                                                 "s72\tS255\tI2\n"
1067                                                 "InstallExecuteSequence\tAction\n"
1068                                                 "CostFinalize\t\t1000\n"
1069                                                 "ValidateProductID\t\t700\n"
1070                                                 "CostInitialize\t\t800\n"
1071                                                 "FileCost\t\t900\n"
1072                                                 "RemoveFiles\t\t3500\n"
1073                                                 "InstallFiles\t\t4000\n"
1074                                                 "RegisterUser\t\t6000\n"
1075                                                 "RegisterProduct\t\t6100\n"
1076                                                 "PublishFeatures\t\t6300\n"
1077                                                 "PublishProduct\t\t6400\n"
1078                                                 "InstallFinalize\t\t6600\n"
1079                                                 "InstallInitialize\t\t1500\n"
1080                                                 "ProcessComponents\t\t1600\n"
1081                                                 "UnpublishFeatures\t\t1800\n"
1082                                                 "InstallValidate\t\t1400\n"
1083                                                 "LaunchConditions\t\t100\n"
1084                                                 "TestAllUsersProp\tALLUSERS=1 AND NOT REMOVE\t50\n";
1085
1086 static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1087                                             "s72\ti2\tS64\tS0\tS255\n"
1088                                             "CustomAction\tAction\n"
1089                                             "TestAllUsersProp\t19\t\tTest failed\t\n";
1090
1091 static const CHAR cf_create_folders_dat[] = "Directory_\tComponent_\n"
1092                                             "s72\ts72\n"
1093                                             "CreateFolder\tDirectory_\tComponent_\n"
1094                                             "FIRSTDIR\tOne\n";
1095
1096 static const CHAR cf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1097                                               "s72\tS255\tI2\n"
1098                                               "InstallExecuteSequence\tAction\n"
1099                                               "CostFinalize\t\t1000\n"
1100                                               "ValidateProductID\t\t700\n"
1101                                               "CostInitialize\t\t800\n"
1102                                               "FileCost\t\t900\n"
1103                                               "RemoveFiles\t\t3500\n"
1104                                               "CreateFolders\t\t3700\n"
1105                                               "InstallExecute\t\t3800\n"
1106                                               "TestCreateFolders\t\t3900\n"
1107                                               "InstallFiles\t\t4000\n"
1108                                               "RegisterUser\t\t6000\n"
1109                                               "RegisterProduct\t\t6100\n"
1110                                               "PublishFeatures\t\t6300\n"
1111                                               "PublishProduct\t\t6400\n"
1112                                               "InstallFinalize\t\t6600\n"
1113                                               "InstallInitialize\t\t1500\n"
1114                                               "ProcessComponents\t\t1600\n"
1115                                               "UnpublishFeatures\t\t1800\n"
1116                                               "InstallValidate\t\t1400\n"
1117                                               "LaunchConditions\t\t100\n";
1118
1119 static const CHAR cf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1120                                            "s72\ti2\tS64\tS0\tS255\n"
1121                                            "CustomAction\tAction\n"
1122                                            "TestCreateFolders\t19\t\tHalts installation\t\n";
1123
1124 static const CHAR rf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1125                                               "s72\tS255\tI2\n"
1126                                               "InstallExecuteSequence\tAction\n"
1127                                               "CostFinalize\t\t1000\n"
1128                                               "ValidateProductID\t\t700\n"
1129                                               "CostInitialize\t\t800\n"
1130                                               "FileCost\t\t900\n"
1131                                               "RemoveFiles\t\t3500\n"
1132                                               "CreateFolders\t\t3600\n"
1133                                               "RemoveFolders\t\t3700\n"
1134                                               "InstallExecute\t\t3800\n"
1135                                               "TestCreateFolders\t\t3900\n"
1136                                               "InstallFiles\t\t4000\n"
1137                                               "RegisterUser\t\t6000\n"
1138                                               "RegisterProduct\t\t6100\n"
1139                                               "PublishFeatures\t\t6300\n"
1140                                               "PublishProduct\t\t6400\n"
1141                                               "InstallFinalize\t\t6600\n"
1142                                               "InstallInitialize\t\t1500\n"
1143                                               "ProcessComponents\t\t1600\n"
1144                                               "UnpublishFeatures\t\t1800\n"
1145                                               "InstallValidate\t\t1400\n"
1146                                               "LaunchConditions\t\t100\n";
1147
1148
1149 static const CHAR sr_selfreg_dat[] = "File_\tCost\n"
1150                                      "s72\tI2\n"
1151                                      "SelfReg\tFile_\n"
1152                                      "one.txt\t1\n";
1153
1154 static const CHAR sr_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1155                                               "s72\tS255\tI2\n"
1156                                               "InstallExecuteSequence\tAction\n"
1157                                               "CostFinalize\t\t1000\n"
1158                                               "CostInitialize\t\t800\n"
1159                                               "FileCost\t\t900\n"
1160                                               "ResolveSource\t\t950\n"
1161                                               "MoveFiles\t\t1700\n"
1162                                               "SelfUnregModules\t\t3900\n"
1163                                               "InstallFiles\t\t4000\n"
1164                                               "DuplicateFiles\t\t4500\n"
1165                                               "WriteEnvironmentStrings\t\t4550\n"
1166                                               "CreateShortcuts\t\t4600\n"
1167                                               "InstallFinalize\t\t6600\n"
1168                                               "InstallInitialize\t\t1500\n"
1169                                               "InstallValidate\t\t1400\n"
1170                                               "LaunchConditions\t\t100\n";
1171
1172 static const CHAR font_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
1173                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
1174                                      "Media\tDiskId\n"
1175                                      "1\t3\t\t\tDISK1\t\n";
1176
1177 static const CHAR font_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1178                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1179                                     "File\tFile\n"
1180                                     "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n";
1181
1182 static const CHAR font_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1183                                        "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1184                                        "Feature\tFeature\n"
1185                                        "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n";
1186
1187 static const CHAR font_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1188                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
1189                                          "Component\tComponent\n"
1190                                          "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n";
1191
1192 static const CHAR font_feature_comp_dat[] = "Feature_\tComponent_\n"
1193                                             "s38\ts72\n"
1194                                             "FeatureComponents\tFeature_\tComponent_\n"
1195                                             "fonts\tfonts\n";
1196
1197 static const CHAR font_dat[] = "File_\tFontTitle\n"
1198                                "s72\tS128\n"
1199                                "Font\tFile_\n"
1200                                "font.ttf\tmsi test font\n";
1201
1202 static const CHAR font_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1203                                                 "s72\tS255\tI2\n"
1204                                                 "InstallExecuteSequence\tAction\n"
1205                                                 "ValidateProductID\t\t700\n"
1206                                                 "CostInitialize\t\t800\n"
1207                                                 "FileCost\t\t900\n"
1208                                                 "CostFinalize\t\t1000\n"
1209                                                 "InstallValidate\t\t1400\n"
1210                                                 "InstallInitialize\t\t1500\n"
1211                                                 "ProcessComponents\t\t1600\n"
1212                                                 "UnpublishFeatures\t\t1800\n"
1213                                                 "RemoveFiles\t\t3500\n"
1214                                                 "InstallFiles\t\t4000\n"
1215                                                 "RegisterFonts\t\t4100\n"
1216                                                 "UnregisterFonts\t\t4200\n"
1217                                                 "RegisterUser\t\t6000\n"
1218                                                 "RegisterProduct\t\t6100\n"
1219                                                 "PublishFeatures\t\t6300\n"
1220                                                 "PublishProduct\t\t6400\n"
1221                                                 "InstallFinalize\t\t6600";
1222
1223 static const CHAR vp_property_dat[] = "Property\tValue\n"
1224                                       "s72\tl0\n"
1225                                       "Property\tProperty\n"
1226                                       "HASUIRUN\t0\n"
1227                                       "INSTALLLEVEL\t3\n"
1228                                       "InstallMode\tTypical\n"
1229                                       "Manufacturer\tWine\n"
1230                                       "PIDTemplate\t###-#######\n"
1231                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
1232                                       "ProductLanguage\t1033\n"
1233                                       "ProductName\tMSITEST\n"
1234                                       "ProductVersion\t1.1.1\n"
1235                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n";
1236
1237 static const CHAR vp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1238                                            "s72\ti2\tS64\tS0\tS255\n"
1239                                            "CustomAction\tAction\n"
1240                                            "SetProductID1\t51\tProductID\t1\t\n"
1241                                            "SetProductID2\t51\tProductID\t2\t\n"
1242                                            "TestProductID1\t19\t\t\tHalts installation\n"
1243                                            "TestProductID2\t19\t\t\tHalts installation\n";
1244
1245 static const CHAR vp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1246                                               "s72\tS255\tI2\n"
1247                                               "InstallExecuteSequence\tAction\n"
1248                                               "LaunchConditions\t\t100\n"
1249                                               "CostInitialize\t\t800\n"
1250                                               "FileCost\t\t900\n"
1251                                               "CostFinalize\t\t1000\n"
1252                                               "InstallValidate\t\t1400\n"
1253                                               "InstallInitialize\t\t1500\n"
1254                                               "SetProductID1\tSET_PRODUCT_ID=1\t3000\n"
1255                                               "SetProductID2\tSET_PRODUCT_ID=2\t3100\n"
1256                                               "ValidateProductID\t\t3200\n"
1257                                               "InstallExecute\t\t3300\n"
1258                                               "TestProductID1\tProductID=1\t3400\n"
1259                                               "TestProductID2\tProductID=\"123-1234567\"\t3500\n"
1260                                               "InstallFiles\t\t4000\n"
1261                                               "InstallFinalize\t\t6000\n";
1262
1263 static const CHAR odbc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1264                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1265                                     "File\tFile\n"
1266                                     "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n"
1267                                     "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n"
1268                                     "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n"
1269                                     "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n"
1270                                     "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n";
1271
1272 static const CHAR odbc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1273                                        "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1274                                        "Feature\tFeature\n"
1275                                        "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n";
1276
1277 static const CHAR odbc_feature_comp_dat[] = "Feature_\tComponent_\n"
1278                                             "s38\ts72\n"
1279                                             "FeatureComponents\tFeature_\tComponent_\n"
1280                                             "odbc\todbc\n";
1281
1282 static const CHAR odbc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1283                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
1284                                          "Component\tComponent\n"
1285                                          "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n";
1286
1287 static const CHAR odbc_driver_dat[] = "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n"
1288                                       "s72\ts72\ts255\ts72\tS72\n"
1289                                       "ODBCDriver\tDriver\n"
1290                                       "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n"
1291                                       "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n";
1292
1293 static const CHAR odbc_translator_dat[] = "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n"
1294                                           "s72\ts72\ts255\ts72\tS72\n"
1295                                           "ODBCTranslator\tTranslator\n"
1296                                           "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n"
1297                                           "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n";
1298
1299 static const CHAR odbc_datasource_dat[] = "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n"
1300                                           "s72\ts72\ts255\ts255\ti2\n"
1301                                           "ODBCDataSource\tDataSource\n"
1302                                           "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n";
1303
1304 static const CHAR odbc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1305                                                 "s72\tS255\tI2\n"
1306                                                 "InstallExecuteSequence\tAction\n"
1307                                                 "LaunchConditions\t\t100\n"
1308                                                 "CostInitialize\t\t800\n"
1309                                                 "FileCost\t\t900\n"
1310                                                 "CostFinalize\t\t1000\n"
1311                                                 "InstallValidate\t\t1400\n"
1312                                                 "InstallInitialize\t\t1500\n"
1313                                                 "InstallODBC\t\t3000\n"
1314                                                 "RemoveODBC\t\t3100\n"
1315                                                 "InstallFiles\t\t4000\n"
1316                                                 "InstallFinalize\t\t6000\n";
1317
1318 static const CHAR odbc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
1319                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
1320                                      "Media\tDiskId\n"
1321                                      "1\t5\t\t\tDISK1\t\n";
1322
1323 static const CHAR tl_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1324                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1325                                   "File\tFile\n"
1326                                   "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
1327
1328 static const CHAR tl_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1329                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1330                                      "Feature\tFeature\n"
1331                                      "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
1332
1333 static const CHAR tl_feature_comp_dat[] = "Feature_\tComponent_\n"
1334                                           "s38\ts72\n"
1335                                           "FeatureComponents\tFeature_\tComponent_\n"
1336                                           "typelib\ttypelib\n";
1337
1338 static const CHAR tl_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1339                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1340                                        "Component\tComponent\n"
1341                                        "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
1342
1343 static const CHAR tl_typelib_dat[] = "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
1344                                      "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
1345                                      "TypeLib\tLibID\tLanguage\tComponent_\n"
1346                                      "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
1347
1348 static const CHAR tl_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1349                                               "s72\tS255\tI2\n"
1350                                               "InstallExecuteSequence\tAction\n"
1351                                               "LaunchConditions\t\t100\n"
1352                                               "CostInitialize\t\t800\n"
1353                                               "FileCost\t\t900\n"
1354                                               "CostFinalize\t\t1000\n"
1355                                               "InstallValidate\t\t1400\n"
1356                                               "InstallInitialize\t\t1500\n"
1357                                               "ProcessComponents\t\t1600\n"
1358                                               "RemoveFiles\t\t1700\n"
1359                                               "InstallFiles\t\t2000\n"
1360                                               "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
1361                                               "UnregisterTypeLibraries\t\t3100\n"
1362                                               "RegisterProduct\t\t5100\n"
1363                                               "PublishFeatures\t\t5200\n"
1364                                               "PublishProduct\t\t5300\n"
1365                                               "InstallFinalize\t\t6000\n";
1366
1367 static const CHAR crs_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1368                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1369                                    "File\tFile\n"
1370                                    "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n";
1371
1372 static const CHAR crs_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1373                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1374                                       "Feature\tFeature\n"
1375                                       "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n";
1376
1377 static const CHAR crs_feature_comp_dat[] = "Feature_\tComponent_\n"
1378                                            "s38\ts72\n"
1379                                            "FeatureComponents\tFeature_\tComponent_\n"
1380                                            "shortcut\tshortcut\n";
1381
1382 static const CHAR crs_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1383                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1384                                         "Component\tComponent\n"
1385                                         "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n";
1386
1387 static const CHAR crs_shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
1388                                        "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n"
1389                                        "Shortcut\tShortcut\n"
1390                                        "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n";
1391
1392 static const CHAR crs_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1393                                                "s72\tS255\tI2\n"
1394                                                "InstallExecuteSequence\tAction\n"
1395                                                "LaunchConditions\t\t100\n"
1396                                                "CostInitialize\t\t800\n"
1397                                                "FileCost\t\t900\n"
1398                                                "CostFinalize\t\t1000\n"
1399                                                "InstallValidate\t\t1400\n"
1400                                                "InstallInitialize\t\t1500\n"
1401                                                "ProcessComponents\t\t1600\n"
1402                                                "RemoveFiles\t\t1700\n"
1403                                                "InstallFiles\t\t2000\n"
1404                                                "RemoveShortcuts\t\t3000\n"
1405                                                "CreateShortcuts\t\t3100\n"
1406                                                "RegisterProduct\t\t5000\n"
1407                                                "PublishFeatures\t\t5100\n"
1408                                                "PublishProduct\t\t5200\n"
1409                                                "InstallFinalize\t\t6000\n";
1410
1411 static const CHAR pub_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1412                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1413                                    "File\tFile\n"
1414                                    "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n";
1415
1416 static const CHAR pub_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1417                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1418                                       "Feature\tFeature\n"
1419                                       "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n";
1420
1421 static const CHAR pub_feature_comp_dat[] = "Feature_\tComponent_\n"
1422                                            "s38\ts72\n"
1423                                            "FeatureComponents\tFeature_\tComponent_\n"
1424                                            "publish\tpublish\n";
1425
1426 static const CHAR pub_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1427                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1428                                         "Component\tComponent\n"
1429                                         "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n";
1430
1431 static const CHAR pub_publish_component_dat[] = "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n"
1432                                                 "s38\ts255\ts72\tL255\ts38\n"
1433                                                 "PublishComponent\tComponentId\tQualifier\tComponent_\n"
1434                                                 "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n";
1435
1436 static const CHAR pub_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1437                                                "s72\tS255\tI2\n"
1438                                                "InstallExecuteSequence\tAction\n"
1439                                                "LaunchConditions\t\t100\n"
1440                                                "CostInitialize\t\t800\n"
1441                                                "FileCost\t\t900\n"
1442                                                "CostFinalize\t\t1000\n"
1443                                                "InstallValidate\t\t1400\n"
1444                                                "InstallInitialize\t\t1500\n"
1445                                                "ProcessComponents\t\t1600\n"
1446                                                "RemoveFiles\t\t1700\n"
1447                                                "InstallFiles\t\t2000\n"
1448                                                "PublishComponents\t\t3000\n"
1449                                                "UnpublishComponents\t\t3100\n"
1450                                                "RegisterProduct\t\t5000\n"
1451                                                "PublishFeatures\t\t5100\n"
1452                                                "PublishProduct\t\t5200\n"
1453                                                "InstallFinalize\t\t6000\n";
1454
1455 static const CHAR rd_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1456                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1457                                   "File\tFile\n"
1458                                   "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n"
1459                                   "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n"
1460                                   "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n";
1461
1462 static const CHAR rd_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1463                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1464                                      "Feature\tFeature\n"
1465                                      "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n";
1466
1467 static const CHAR rd_feature_comp_dat[] = "Feature_\tComponent_\n"
1468                                           "s38\ts72\n"
1469                                           "FeatureComponents\tFeature_\tComponent_\n"
1470                                           "duplicate\tduplicate\n";
1471
1472 static const CHAR rd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1473                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1474                                        "Component\tComponent\n"
1475                                        "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n"
1476                                        "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n";
1477
1478 static const CHAR rd_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
1479                                             "s72\ts72\ts72\tS255\tS72\n"
1480                                             "DuplicateFile\tFileKey\n"
1481                                             "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n"
1482                                             "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n"
1483                                             "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n";
1484
1485 static const CHAR rd_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1486                                               "s72\tS255\tI2\n"
1487                                               "InstallExecuteSequence\tAction\n"
1488                                               "LaunchConditions\t\t100\n"
1489                                               "CostInitialize\t\t800\n"
1490                                               "FileCost\t\t900\n"
1491                                               "CostFinalize\t\t1000\n"
1492                                               "InstallValidate\t\t1400\n"
1493                                               "InstallInitialize\t\t1500\n"
1494                                               "ProcessComponents\t\t1600\n"
1495                                               "RemoveDuplicateFiles\t\t1900\n"
1496                                               "InstallFiles\t\t2000\n"
1497                                               "DuplicateFiles\t\t2100\n"
1498                                               "RegisterProduct\t\t5000\n"
1499                                               "PublishFeatures\t\t5100\n"
1500                                               "PublishProduct\t\t5200\n"
1501                                               "InstallFinalize\t\t6000\n";
1502
1503 static const CHAR rrv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1504                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1505                                    "File\tFile\n"
1506                                    "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n";
1507
1508 static const CHAR rrv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1509                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1510                                       "Feature\tFeature\n"
1511                                       "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n";
1512
1513 static const CHAR rrv_feature_comp_dat[] = "Feature_\tComponent_\n"
1514                                            "s38\ts72\n"
1515                                            "FeatureComponents\tFeature_\tComponent_\n"
1516                                            "registry\tregistry\n";
1517
1518 static const CHAR rrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1519                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1520                                         "Component\tComponent\n"
1521                                         "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n";
1522
1523 static const CHAR rrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
1524                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
1525                                        "Registry\tRegistry\n"
1526                                        "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n"
1527                                        "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n"
1528                                        "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n";
1529
1530 static const CHAR rrv_remove_registry_dat[] = "RemoveRegistry\tRoot\tKey\tName\tComponent_\n"
1531                                               "s72\ti2\tl255\tL255\ts72\n"
1532                                               "RemoveRegistry\tRemoveRegistry\n"
1533                                               "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n"
1534                                               "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n"
1535                                               "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n";
1536
1537 static const CHAR rrv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1538                                                "s72\tS255\tI2\n"
1539                                                "InstallExecuteSequence\tAction\n"
1540                                                "LaunchConditions\t\t100\n"
1541                                                "CostInitialize\t\t800\n"
1542                                                "FileCost\t\t900\n"
1543                                                "CostFinalize\t\t1000\n"
1544                                                "InstallValidate\t\t1400\n"
1545                                                "InstallInitialize\t\t1500\n"
1546                                                "ProcessComponents\t\t1600\n"
1547                                                "RemoveFiles\t\t1700\n"
1548                                                "InstallFiles\t\t2000\n"
1549                                                "RemoveRegistryValues\t\t3000\n"
1550                                                "RegisterProduct\t\t5000\n"
1551                                                "PublishFeatures\t\t5100\n"
1552                                                "PublishProduct\t\t5200\n"
1553                                                "InstallFinalize\t\t6000\n";
1554
1555 static const CHAR frp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1556                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1557                                    "File\tFile\n"
1558                                    "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n";
1559
1560 static const CHAR frp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1561                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1562                                       "Feature\tFeature\n"
1563                                       "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n";
1564
1565 static const CHAR frp_feature_comp_dat[] = "Feature_\tComponent_\n"
1566                                            "s38\ts72\n"
1567                                            "FeatureComponents\tFeature_\tComponent_\n"
1568                                            "product\tproduct\n";
1569
1570 static const CHAR frp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1571                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1572                                         "Component\tComponent\n"
1573                                         "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n";
1574
1575 static const CHAR frp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1576                                             "s72\ti2\tS64\tS0\tS255\n"
1577                                             "CustomAction\tAction\n"
1578                                             "TestProp\t19\t\t\tPROP set\n";
1579
1580 static const CHAR frp_upgrade_dat[] = "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1581                                       "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1582                                       "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1583                                       "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n";
1584
1585 static const CHAR frp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1586                                                "s72\tS255\tI2\n"
1587                                                "InstallExecuteSequence\tAction\n"
1588                                                "FindRelatedProducts\t\t50\n"
1589                                                "TestProp\tPROP AND NOT REMOVE\t51\n"
1590                                                "LaunchConditions\t\t100\n"
1591                                                "CostInitialize\t\t800\n"
1592                                                "FileCost\t\t900\n"
1593                                                "CostFinalize\t\t1000\n"
1594                                                "InstallValidate\t\t1400\n"
1595                                                "InstallInitialize\t\t1500\n"
1596                                                "ProcessComponents\t\t1600\n"
1597                                                "RemoveFiles\t\t1700\n"
1598                                                "InstallFiles\t\t2000\n"
1599                                                "RegisterProduct\t\t5000\n"
1600                                                "PublishFeatures\t\t5100\n"
1601                                                "PublishProduct\t\t5200\n"
1602                                                "InstallFinalize\t\t6000\n";
1603
1604 static const CHAR riv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1605                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1606                                    "File\tFile\n"
1607                                    "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n";
1608
1609 static const CHAR riv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1610                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1611                                       "Feature\tFeature\n"
1612                                       "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n";
1613
1614 static const CHAR riv_feature_comp_dat[] = "Feature_\tComponent_\n"
1615                                            "s38\ts72\n"
1616                                            "FeatureComponents\tFeature_\tComponent_\n"
1617                                            "inifile\tinifile\n";
1618
1619 static const CHAR riv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1620                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1621                                         "Component\tComponent\n"
1622                                         "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n";
1623
1624 static const CHAR riv_ini_file_dat[] = "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1625                                        "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n"
1626                                        "IniFile\tIniFile\n"
1627                                        "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n";
1628
1629 static const CHAR riv_remove_ini_file_dat[] = "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1630                                               "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n"
1631                                               "RemoveIniFile\tRemoveIniFile\n"
1632                                               "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n";
1633
1634 static const CHAR riv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1635                                                "s72\tS255\tI2\n"
1636                                                "InstallExecuteSequence\tAction\n"
1637                                                "LaunchConditions\t\t100\n"
1638                                                "CostInitialize\t\t800\n"
1639                                                "FileCost\t\t900\n"
1640                                                "CostFinalize\t\t1000\n"
1641                                                "InstallValidate\t\t1400\n"
1642                                                "InstallInitialize\t\t1500\n"
1643                                                "ProcessComponents\t\t1600\n"
1644                                                "RemoveFiles\t\t1700\n"
1645                                                "InstallFiles\t\t2000\n"
1646                                                "RemoveIniValues\t\t3000\n"
1647                                                "RegisterProduct\t\t5000\n"
1648                                                "PublishFeatures\t\t5100\n"
1649                                                "PublishProduct\t\t5200\n"
1650                                                "InstallFinalize\t\t6000\n";
1651
1652 static const CHAR res_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1653                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1654                                    "File\tFile\n"
1655                                    "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n";
1656
1657 static const CHAR res_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1658                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1659                                       "Feature\tFeature\n"
1660                                       "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n";
1661
1662 static const CHAR res_feature_comp_dat[] = "Feature_\tComponent_\n"
1663                                            "s38\ts72\n"
1664                                            "FeatureComponents\tFeature_\tComponent_\n"
1665                                            "envvar\tenvvar\n";
1666
1667 static const CHAR res_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1668                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1669                                         "Component\tComponent\n"
1670                                         "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n";
1671
1672 static const CHAR res_environment_dat[] = "Environment\tName\tValue\tComponent_\n"
1673                                           "s72\tl255\tL255\ts72\n"
1674                                           "Environment\tEnvironment\n"
1675                                           "var1\t=-MSITESTVAR1\t1\tenvvar\n"
1676                                           "var2\t=+-MSITESTVAR2\t1\tenvvar\n"
1677                                           "var3\t=MSITESTVAR3\t1\tenvvar\n"
1678                                           "var4\t=-MSITESTVAR4\t\tenvvar\n"
1679                                           "var5\t=MSITESTVAR5\t\tenvvar\n";
1680
1681 static const CHAR res_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1682                                                "s72\tS255\tI2\n"
1683                                                "InstallExecuteSequence\tAction\n"
1684                                                "LaunchConditions\t\t100\n"
1685                                                "CostInitialize\t\t800\n"
1686                                                "FileCost\t\t900\n"
1687                                                "CostFinalize\t\t1000\n"
1688                                                "InstallValidate\t\t1400\n"
1689                                                "InstallInitialize\t\t1500\n"
1690                                                "ProcessComponents\t\t1600\n"
1691                                                "RemoveFiles\t\t1700\n"
1692                                                "InstallFiles\t\t2000\n"
1693                                                "RemoveEnvironmentStrings\t\t3000\n"
1694                                                "RegisterProduct\t\t5000\n"
1695                                                "PublishFeatures\t\t5100\n"
1696                                                "PublishProduct\t\t5200\n"
1697                                                "InstallFinalize\t\t6000\n";
1698
1699 typedef struct _msi_table
1700 {
1701     const CHAR *filename;
1702     const CHAR *data;
1703     int size;
1704 } msi_table;
1705
1706 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
1707
1708 static const msi_table tables[] =
1709 {
1710     ADD_TABLE(component),
1711     ADD_TABLE(directory),
1712     ADD_TABLE(feature),
1713     ADD_TABLE(feature_comp),
1714     ADD_TABLE(file),
1715     ADD_TABLE(install_exec_seq),
1716     ADD_TABLE(media),
1717     ADD_TABLE(property),
1718     ADD_TABLE(registry),
1719     ADD_TABLE(service_install),
1720     ADD_TABLE(service_control)
1721 };
1722
1723 static const msi_table sc_tables[] =
1724 {
1725     ADD_TABLE(component),
1726     ADD_TABLE(directory),
1727     ADD_TABLE(feature),
1728     ADD_TABLE(feature_comp),
1729     ADD_TABLE(file),
1730     ADD_TABLE(install_exec_seq),
1731     ADD_TABLE(media),
1732     ADD_TABLE(property),
1733     ADD_TABLE(shortcut)
1734 };
1735
1736 static const msi_table ps_tables[] =
1737 {
1738     ADD_TABLE(component),
1739     ADD_TABLE(directory),
1740     ADD_TABLE(feature),
1741     ADD_TABLE(feature_comp),
1742     ADD_TABLE(file),
1743     ADD_TABLE(install_exec_seq),
1744     ADD_TABLE(media),
1745     ADD_TABLE(property),
1746     ADD_TABLE(condition)
1747 };
1748
1749 static const msi_table env_tables[] =
1750 {
1751     ADD_TABLE(component),
1752     ADD_TABLE(directory),
1753     ADD_TABLE(feature),
1754     ADD_TABLE(feature_comp),
1755     ADD_TABLE(file),
1756     ADD_TABLE(install_exec_seq),
1757     ADD_TABLE(media),
1758     ADD_TABLE(property),
1759     ADD_TABLE(environment)
1760 };
1761
1762 static const msi_table up_tables[] =
1763 {
1764     ADD_TABLE(component),
1765     ADD_TABLE(directory),
1766     ADD_TABLE(feature),
1767     ADD_TABLE(feature_comp),
1768     ADD_TABLE(file),
1769     ADD_TABLE(install_exec_seq),
1770     ADD_TABLE(media),
1771     ADD_TABLE(up_property),
1772     ADD_TABLE(registry),
1773     ADD_TABLE(service_install),
1774     ADD_TABLE(service_control)
1775 };
1776
1777 static const msi_table up2_tables[] =
1778 {
1779     ADD_TABLE(component),
1780     ADD_TABLE(directory),
1781     ADD_TABLE(feature),
1782     ADD_TABLE(feature_comp),
1783     ADD_TABLE(file),
1784     ADD_TABLE(install_exec_seq),
1785     ADD_TABLE(media),
1786     ADD_TABLE(up2_property),
1787     ADD_TABLE(registry),
1788     ADD_TABLE(service_install),
1789     ADD_TABLE(service_control)
1790 };
1791
1792 static const msi_table up3_tables[] =
1793 {
1794     ADD_TABLE(component),
1795     ADD_TABLE(directory),
1796     ADD_TABLE(feature),
1797     ADD_TABLE(feature_comp),
1798     ADD_TABLE(file),
1799     ADD_TABLE(install_exec_seq),
1800     ADD_TABLE(media),
1801     ADD_TABLE(up3_property),
1802     ADD_TABLE(registry),
1803     ADD_TABLE(service_install),
1804     ADD_TABLE(service_control)
1805 };
1806
1807 static const msi_table up4_tables[] =
1808 {
1809     ADD_TABLE(component),
1810     ADD_TABLE(directory),
1811     ADD_TABLE(feature),
1812     ADD_TABLE(feature_comp),
1813     ADD_TABLE(file),
1814     ADD_TABLE(pp_install_exec_seq),
1815     ADD_TABLE(media),
1816     ADD_TABLE(property),
1817     ADD_TABLE(registry),
1818     ADD_TABLE(service_install),
1819     ADD_TABLE(service_control)
1820 };
1821
1822 static const msi_table up5_tables[] =
1823 {
1824     ADD_TABLE(component),
1825     ADD_TABLE(directory),
1826     ADD_TABLE(feature),
1827     ADD_TABLE(feature_comp),
1828     ADD_TABLE(file),
1829     ADD_TABLE(pp_install_exec_seq),
1830     ADD_TABLE(media),
1831     ADD_TABLE(up_property),
1832     ADD_TABLE(registry),
1833     ADD_TABLE(service_install),
1834     ADD_TABLE(service_control)
1835 };
1836
1837 static const msi_table up6_tables[] =
1838 {
1839     ADD_TABLE(component),
1840     ADD_TABLE(directory),
1841     ADD_TABLE(feature),
1842     ADD_TABLE(feature_comp),
1843     ADD_TABLE(file),
1844     ADD_TABLE(pp_install_exec_seq),
1845     ADD_TABLE(media),
1846     ADD_TABLE(up2_property),
1847     ADD_TABLE(registry),
1848     ADD_TABLE(service_install),
1849     ADD_TABLE(service_control)
1850 };
1851
1852 static const msi_table up7_tables[] =
1853 {
1854     ADD_TABLE(component),
1855     ADD_TABLE(directory),
1856     ADD_TABLE(feature),
1857     ADD_TABLE(feature_comp),
1858     ADD_TABLE(file),
1859     ADD_TABLE(pp_install_exec_seq),
1860     ADD_TABLE(media),
1861     ADD_TABLE(up3_property),
1862     ADD_TABLE(registry),
1863     ADD_TABLE(service_install),
1864     ADD_TABLE(service_control)
1865 };
1866
1867 static const msi_table cc_tables[] =
1868 {
1869     ADD_TABLE(cc_component),
1870     ADD_TABLE(directory),
1871     ADD_TABLE(cc_feature),
1872     ADD_TABLE(cc_feature_comp),
1873     ADD_TABLE(cc_file),
1874     ADD_TABLE(install_exec_seq),
1875     ADD_TABLE(cc_media),
1876     ADD_TABLE(property),
1877 };
1878
1879 static const msi_table cc2_tables[] =
1880 {
1881     ADD_TABLE(cc2_component),
1882     ADD_TABLE(directory),
1883     ADD_TABLE(cc_feature),
1884     ADD_TABLE(cc_feature_comp),
1885     ADD_TABLE(cc2_file),
1886     ADD_TABLE(install_exec_seq),
1887     ADD_TABLE(cc_media),
1888     ADD_TABLE(property),
1889 };
1890
1891 static const msi_table co_tables[] =
1892 {
1893     ADD_TABLE(cc_component),
1894     ADD_TABLE(directory),
1895     ADD_TABLE(cc_feature),
1896     ADD_TABLE(cc_feature_comp),
1897     ADD_TABLE(co_file),
1898     ADD_TABLE(install_exec_seq),
1899     ADD_TABLE(co_media),
1900     ADD_TABLE(property),
1901 };
1902
1903 static const msi_table co2_tables[] =
1904 {
1905     ADD_TABLE(cc_component),
1906     ADD_TABLE(directory),
1907     ADD_TABLE(cc_feature),
1908     ADD_TABLE(cc_feature_comp),
1909     ADD_TABLE(cc_file),
1910     ADD_TABLE(install_exec_seq),
1911     ADD_TABLE(co2_media),
1912     ADD_TABLE(property),
1913 };
1914
1915 static const msi_table mm_tables[] =
1916 {
1917     ADD_TABLE(cc_component),
1918     ADD_TABLE(directory),
1919     ADD_TABLE(cc_feature),
1920     ADD_TABLE(cc_feature_comp),
1921     ADD_TABLE(mm_file),
1922     ADD_TABLE(install_exec_seq),
1923     ADD_TABLE(mm_media),
1924     ADD_TABLE(property),
1925 };
1926
1927 static const msi_table ss_tables[] =
1928 {
1929     ADD_TABLE(cc_component),
1930     ADD_TABLE(directory),
1931     ADD_TABLE(cc_feature),
1932     ADD_TABLE(cc_feature_comp),
1933     ADD_TABLE(cc_file),
1934     ADD_TABLE(install_exec_seq),
1935     ADD_TABLE(ss_media),
1936     ADD_TABLE(property),
1937 };
1938
1939 static const msi_table ui_tables[] =
1940 {
1941     ADD_TABLE(ui_component),
1942     ADD_TABLE(directory),
1943     ADD_TABLE(cc_feature),
1944     ADD_TABLE(cc_feature_comp),
1945     ADD_TABLE(cc_file),
1946     ADD_TABLE(install_exec_seq),
1947     ADD_TABLE(ui_install_ui_seq),
1948     ADD_TABLE(ui_custom_action),
1949     ADD_TABLE(cc_media),
1950     ADD_TABLE(property),
1951 };
1952
1953 static const msi_table rof_tables[] =
1954 {
1955     ADD_TABLE(rof_component),
1956     ADD_TABLE(directory),
1957     ADD_TABLE(rof_feature),
1958     ADD_TABLE(rof_feature_comp),
1959     ADD_TABLE(rof_file),
1960     ADD_TABLE(install_exec_seq),
1961     ADD_TABLE(rof_media),
1962     ADD_TABLE(property),
1963 };
1964
1965 static const msi_table rofc_tables[] =
1966 {
1967     ADD_TABLE(rof_component),
1968     ADD_TABLE(directory),
1969     ADD_TABLE(rof_feature),
1970     ADD_TABLE(rof_feature_comp),
1971     ADD_TABLE(rofc_file),
1972     ADD_TABLE(install_exec_seq),
1973     ADD_TABLE(rofc_media),
1974     ADD_TABLE(property),
1975 };
1976
1977 static const msi_table sdp_tables[] =
1978 {
1979     ADD_TABLE(rof_component),
1980     ADD_TABLE(directory),
1981     ADD_TABLE(rof_feature),
1982     ADD_TABLE(rof_feature_comp),
1983     ADD_TABLE(rof_file),
1984     ADD_TABLE(sdp_install_exec_seq),
1985     ADD_TABLE(sdp_custom_action),
1986     ADD_TABLE(rof_media),
1987     ADD_TABLE(property),
1988 };
1989
1990 static const msi_table cie_tables[] =
1991 {
1992     ADD_TABLE(cie_component),
1993     ADD_TABLE(directory),
1994     ADD_TABLE(cc_feature),
1995     ADD_TABLE(cie_feature_comp),
1996     ADD_TABLE(cie_file),
1997     ADD_TABLE(install_exec_seq),
1998     ADD_TABLE(cie_media),
1999     ADD_TABLE(property),
2000 };
2001
2002 static const msi_table ci_tables[] =
2003 {
2004     ADD_TABLE(ci_component),
2005     ADD_TABLE(directory),
2006     ADD_TABLE(rof_feature),
2007     ADD_TABLE(rof_feature_comp),
2008     ADD_TABLE(rof_file),
2009     ADD_TABLE(ci_install_exec_seq),
2010     ADD_TABLE(rof_media),
2011     ADD_TABLE(property),
2012     ADD_TABLE(ci_custom_action),
2013 };
2014
2015 static const msi_table ci2_tables[] =
2016 {
2017     ADD_TABLE(ci2_component),
2018     ADD_TABLE(directory),
2019     ADD_TABLE(rof_feature),
2020     ADD_TABLE(ci2_feature_comp),
2021     ADD_TABLE(ci2_file),
2022     ADD_TABLE(install_exec_seq),
2023     ADD_TABLE(rof_media),
2024     ADD_TABLE(property),
2025 };
2026
2027 static const msi_table spf_tables[] =
2028 {
2029     ADD_TABLE(ci_component),
2030     ADD_TABLE(directory),
2031     ADD_TABLE(rof_feature),
2032     ADD_TABLE(rof_feature_comp),
2033     ADD_TABLE(rof_file),
2034     ADD_TABLE(spf_install_exec_seq),
2035     ADD_TABLE(rof_media),
2036     ADD_TABLE(property),
2037     ADD_TABLE(spf_custom_action),
2038     ADD_TABLE(spf_install_ui_seq),
2039 };
2040
2041 static const msi_table pp_tables[] =
2042 {
2043     ADD_TABLE(ci_component),
2044     ADD_TABLE(directory),
2045     ADD_TABLE(rof_feature),
2046     ADD_TABLE(rof_feature_comp),
2047     ADD_TABLE(rof_file),
2048     ADD_TABLE(pp_install_exec_seq),
2049     ADD_TABLE(rof_media),
2050     ADD_TABLE(property),
2051 };
2052
2053 static const msi_table ppc_tables[] =
2054 {
2055     ADD_TABLE(ppc_component),
2056     ADD_TABLE(directory),
2057     ADD_TABLE(rof_feature),
2058     ADD_TABLE(ppc_feature_comp),
2059     ADD_TABLE(ppc_file),
2060     ADD_TABLE(pp_install_exec_seq),
2061     ADD_TABLE(ppc_media),
2062     ADD_TABLE(property),
2063 };
2064
2065 static const msi_table lus0_tables[] =
2066 {
2067     ADD_TABLE(ci_component),
2068     ADD_TABLE(directory),
2069     ADD_TABLE(rof_feature),
2070     ADD_TABLE(rof_feature_comp),
2071     ADD_TABLE(rof_file),
2072     ADD_TABLE(pp_install_exec_seq),
2073     ADD_TABLE(rof_media),
2074     ADD_TABLE(property),
2075 };
2076
2077 static const msi_table lus1_tables[] =
2078 {
2079     ADD_TABLE(ci_component),
2080     ADD_TABLE(directory),
2081     ADD_TABLE(rof_feature),
2082     ADD_TABLE(rof_feature_comp),
2083     ADD_TABLE(rof_file),
2084     ADD_TABLE(pp_install_exec_seq),
2085     ADD_TABLE(rofc_media),
2086     ADD_TABLE(property),
2087 };
2088
2089 static const msi_table lus2_tables[] =
2090 {
2091     ADD_TABLE(ci_component),
2092     ADD_TABLE(directory),
2093     ADD_TABLE(rof_feature),
2094     ADD_TABLE(rof_feature_comp),
2095     ADD_TABLE(rof_file),
2096     ADD_TABLE(pp_install_exec_seq),
2097     ADD_TABLE(lus2_media),
2098     ADD_TABLE(property),
2099 };
2100
2101 static const msi_table tp_tables[] =
2102 {
2103     ADD_TABLE(tp_component),
2104     ADD_TABLE(directory),
2105     ADD_TABLE(rof_feature),
2106     ADD_TABLE(ci2_feature_comp),
2107     ADD_TABLE(ci2_file),
2108     ADD_TABLE(install_exec_seq),
2109     ADD_TABLE(rof_media),
2110     ADD_TABLE(property),
2111 };
2112
2113 static const msi_table cwd_tables[] =
2114 {
2115     ADD_TABLE(cwd_component),
2116     ADD_TABLE(directory),
2117     ADD_TABLE(rof_feature),
2118     ADD_TABLE(ci2_feature_comp),
2119     ADD_TABLE(ci2_file),
2120     ADD_TABLE(install_exec_seq),
2121     ADD_TABLE(rof_media),
2122     ADD_TABLE(property),
2123 };
2124
2125 static const msi_table adm_tables[] =
2126 {
2127     ADD_TABLE(adm_component),
2128     ADD_TABLE(directory),
2129     ADD_TABLE(rof_feature),
2130     ADD_TABLE(ci2_feature_comp),
2131     ADD_TABLE(ci2_file),
2132     ADD_TABLE(install_exec_seq),
2133     ADD_TABLE(rof_media),
2134     ADD_TABLE(property),
2135     ADD_TABLE(adm_custom_action),
2136     ADD_TABLE(adm_admin_exec_seq),
2137 };
2138
2139 static const msi_table amp_tables[] =
2140 {
2141     ADD_TABLE(amp_component),
2142     ADD_TABLE(directory),
2143     ADD_TABLE(rof_feature),
2144     ADD_TABLE(ci2_feature_comp),
2145     ADD_TABLE(ci2_file),
2146     ADD_TABLE(install_exec_seq),
2147     ADD_TABLE(rof_media),
2148     ADD_TABLE(property),
2149 };
2150
2151 static const msi_table rem_tables[] =
2152 {
2153     ADD_TABLE(rem_component),
2154     ADD_TABLE(directory),
2155     ADD_TABLE(rof_feature),
2156     ADD_TABLE(rem_feature_comp),
2157     ADD_TABLE(rem_file),
2158     ADD_TABLE(rem_install_exec_seq),
2159     ADD_TABLE(rof_media),
2160     ADD_TABLE(property),
2161     ADD_TABLE(rem_remove_files),
2162 };
2163
2164 static const msi_table mov_tables[] =
2165 {
2166     ADD_TABLE(cwd_component),
2167     ADD_TABLE(directory),
2168     ADD_TABLE(rof_feature),
2169     ADD_TABLE(ci2_feature_comp),
2170     ADD_TABLE(ci2_file),
2171     ADD_TABLE(install_exec_seq),
2172     ADD_TABLE(rof_media),
2173     ADD_TABLE(property),
2174     ADD_TABLE(mov_move_file),
2175 };
2176
2177 static const msi_table mc_tables[] =
2178 {
2179     ADD_TABLE(mc_component),
2180     ADD_TABLE(directory),
2181     ADD_TABLE(cc_feature),
2182     ADD_TABLE(cie_feature_comp),
2183     ADD_TABLE(mc_file),
2184     ADD_TABLE(install_exec_seq),
2185     ADD_TABLE(mc_media),
2186     ADD_TABLE(property),
2187     ADD_TABLE(mc_file_hash),
2188 };
2189
2190 static const msi_table df_tables[] =
2191 {
2192     ADD_TABLE(rof_component),
2193     ADD_TABLE(df_directory),
2194     ADD_TABLE(rof_feature),
2195     ADD_TABLE(rof_feature_comp),
2196     ADD_TABLE(rof_file),
2197     ADD_TABLE(install_exec_seq),
2198     ADD_TABLE(rof_media),
2199     ADD_TABLE(property),
2200     ADD_TABLE(df_duplicate_file),
2201 };
2202
2203 static const msi_table wrv_tables[] =
2204 {
2205     ADD_TABLE(wrv_component),
2206     ADD_TABLE(directory),
2207     ADD_TABLE(rof_feature),
2208     ADD_TABLE(ci2_feature_comp),
2209     ADD_TABLE(ci2_file),
2210     ADD_TABLE(install_exec_seq),
2211     ADD_TABLE(rof_media),
2212     ADD_TABLE(property),
2213     ADD_TABLE(wrv_registry),
2214 };
2215
2216 static const msi_table sf_tables[] =
2217 {
2218     ADD_TABLE(wrv_component),
2219     ADD_TABLE(directory),
2220     ADD_TABLE(rof_feature),
2221     ADD_TABLE(ci2_feature_comp),
2222     ADD_TABLE(ci2_file),
2223     ADD_TABLE(install_exec_seq),
2224     ADD_TABLE(rof_media),
2225     ADD_TABLE(property),
2226 };
2227
2228 static const msi_table ca51_tables[] =
2229 {
2230     ADD_TABLE(ca51_component),
2231     ADD_TABLE(directory),
2232     ADD_TABLE(rof_feature),
2233     ADD_TABLE(ci2_feature_comp),
2234     ADD_TABLE(ci2_file),
2235     ADD_TABLE(ca51_install_exec_seq),
2236     ADD_TABLE(rof_media),
2237     ADD_TABLE(property),
2238     ADD_TABLE(ca51_custom_action),
2239 };
2240
2241 static const msi_table is_tables[] =
2242 {
2243     ADD_TABLE(is_component),
2244     ADD_TABLE(directory),
2245     ADD_TABLE(is_feature),
2246     ADD_TABLE(is_feature_comp),
2247     ADD_TABLE(is_file),
2248     ADD_TABLE(install_exec_seq),
2249     ADD_TABLE(is_media),
2250     ADD_TABLE(property),
2251 };
2252
2253 static const msi_table sp_tables[] =
2254 {
2255     ADD_TABLE(sp_component),
2256     ADD_TABLE(sp_directory),
2257     ADD_TABLE(rof_feature),
2258     ADD_TABLE(ci2_feature_comp),
2259     ADD_TABLE(ci2_file),
2260     ADD_TABLE(install_exec_seq),
2261     ADD_TABLE(rof_media),
2262     ADD_TABLE(property),
2263 };
2264
2265 static const msi_table mcp_tables[] =
2266 {
2267     ADD_TABLE(mcp_component),
2268     ADD_TABLE(directory),
2269     ADD_TABLE(mcp_feature),
2270     ADD_TABLE(mcp_feature_comp),
2271     ADD_TABLE(rem_file),
2272     ADD_TABLE(rem_install_exec_seq),
2273     ADD_TABLE(rof_media),
2274     ADD_TABLE(property),
2275 };
2276
2277 static const msi_table mcomp_tables[] =
2278 {
2279     ADD_TABLE(mcp_component),
2280     ADD_TABLE(directory),
2281     ADD_TABLE(mcp_feature),
2282     ADD_TABLE(mcp_feature_comp),
2283     ADD_TABLE(mcomp_file),
2284     ADD_TABLE(rem_install_exec_seq),
2285     ADD_TABLE(rof_media),
2286     ADD_TABLE(property),
2287 };
2288
2289 static const msi_table ai_tables[] =
2290 {
2291     ADD_TABLE(component),
2292     ADD_TABLE(directory),
2293     ADD_TABLE(feature),
2294     ADD_TABLE(feature_comp),
2295     ADD_TABLE(ai_file),
2296     ADD_TABLE(install_exec_seq),
2297     ADD_TABLE(media),
2298     ADD_TABLE(property)
2299 };
2300
2301 static const msi_table pc_tables[] =
2302 {
2303     ADD_TABLE(ca51_component),
2304     ADD_TABLE(directory),
2305     ADD_TABLE(rof_feature),
2306     ADD_TABLE(ci2_feature_comp),
2307     ADD_TABLE(ci2_file),
2308     ADD_TABLE(install_exec_seq),
2309     ADD_TABLE(rof_media),
2310     ADD_TABLE(property)
2311 };
2312
2313 static const msi_table ip_tables[] =
2314 {
2315     ADD_TABLE(component),
2316     ADD_TABLE(directory),
2317     ADD_TABLE(feature),
2318     ADD_TABLE(feature_comp),
2319     ADD_TABLE(file),
2320     ADD_TABLE(ip_install_exec_seq),
2321     ADD_TABLE(ip_custom_action),
2322     ADD_TABLE(media),
2323     ADD_TABLE(property)
2324 };
2325
2326 static const msi_table aup_tables[] =
2327 {
2328     ADD_TABLE(component),
2329     ADD_TABLE(directory),
2330     ADD_TABLE(feature),
2331     ADD_TABLE(feature_comp),
2332     ADD_TABLE(file),
2333     ADD_TABLE(aup_install_exec_seq),
2334     ADD_TABLE(aup_custom_action),
2335     ADD_TABLE(media),
2336     ADD_TABLE(property)
2337 };
2338
2339 static const msi_table aup2_tables[] =
2340 {
2341     ADD_TABLE(component),
2342     ADD_TABLE(directory),
2343     ADD_TABLE(feature),
2344     ADD_TABLE(feature_comp),
2345     ADD_TABLE(file),
2346     ADD_TABLE(aup2_install_exec_seq),
2347     ADD_TABLE(aup_custom_action),
2348     ADD_TABLE(media),
2349     ADD_TABLE(aup_property)
2350 };
2351
2352 static const msi_table aup3_tables[] =
2353 {
2354     ADD_TABLE(component),
2355     ADD_TABLE(directory),
2356     ADD_TABLE(feature),
2357     ADD_TABLE(feature_comp),
2358     ADD_TABLE(file),
2359     ADD_TABLE(aup2_install_exec_seq),
2360     ADD_TABLE(aup_custom_action),
2361     ADD_TABLE(media),
2362     ADD_TABLE(aup2_property)
2363 };
2364
2365 static const msi_table aup4_tables[] =
2366 {
2367     ADD_TABLE(component),
2368     ADD_TABLE(directory),
2369     ADD_TABLE(feature),
2370     ADD_TABLE(feature_comp),
2371     ADD_TABLE(file),
2372     ADD_TABLE(aup3_install_exec_seq),
2373     ADD_TABLE(aup_custom_action),
2374     ADD_TABLE(media),
2375     ADD_TABLE(aup2_property)
2376 };
2377
2378 static const msi_table fiu_tables[] =
2379 {
2380     ADD_TABLE(rof_component),
2381     ADD_TABLE(directory),
2382     ADD_TABLE(rof_feature),
2383     ADD_TABLE(rof_feature_comp),
2384     ADD_TABLE(rof_file),
2385     ADD_TABLE(pp_install_exec_seq),
2386     ADD_TABLE(rof_media),
2387     ADD_TABLE(property),
2388 };
2389
2390 static const msi_table fiuc_tables[] =
2391 {
2392     ADD_TABLE(rof_component),
2393     ADD_TABLE(directory),
2394     ADD_TABLE(rof_feature),
2395     ADD_TABLE(rof_feature_comp),
2396     ADD_TABLE(rofc_file),
2397     ADD_TABLE(pp_install_exec_seq),
2398     ADD_TABLE(rofc_media),
2399     ADD_TABLE(property),
2400 };
2401
2402 static const msi_table cf_tables[] =
2403 {
2404     ADD_TABLE(component),
2405     ADD_TABLE(directory),
2406     ADD_TABLE(feature),
2407     ADD_TABLE(feature_comp),
2408     ADD_TABLE(file),
2409     ADD_TABLE(cf_create_folders),
2410     ADD_TABLE(cf_install_exec_seq),
2411     ADD_TABLE(cf_custom_action),
2412     ADD_TABLE(media),
2413     ADD_TABLE(property)
2414 };
2415
2416 static const msi_table rf_tables[] =
2417 {
2418     ADD_TABLE(component),
2419     ADD_TABLE(directory),
2420     ADD_TABLE(feature),
2421     ADD_TABLE(feature_comp),
2422     ADD_TABLE(file),
2423     ADD_TABLE(cf_create_folders),
2424     ADD_TABLE(rf_install_exec_seq),
2425     ADD_TABLE(cf_custom_action),
2426     ADD_TABLE(media),
2427     ADD_TABLE(property)
2428 };
2429
2430 static const msi_table sss_tables[] =
2431 {
2432     ADD_TABLE(component),
2433     ADD_TABLE(directory),
2434     ADD_TABLE(feature),
2435     ADD_TABLE(feature_comp),
2436     ADD_TABLE(file),
2437     ADD_TABLE(sss_install_exec_seq),
2438     ADD_TABLE(sss_service_control),
2439     ADD_TABLE(media),
2440     ADD_TABLE(property)
2441 };
2442
2443 static const msi_table sds_tables[] =
2444 {
2445     ADD_TABLE(component),
2446     ADD_TABLE(directory),
2447     ADD_TABLE(feature),
2448     ADD_TABLE(feature_comp),
2449     ADD_TABLE(file),
2450     ADD_TABLE(sss_install_exec_seq),
2451     ADD_TABLE(service_control),
2452     ADD_TABLE(media),
2453     ADD_TABLE(property)
2454 };
2455
2456 static const msi_table sr_tables[] =
2457 {
2458     ADD_TABLE(component),
2459     ADD_TABLE(directory),
2460     ADD_TABLE(feature),
2461     ADD_TABLE(feature_comp),
2462     ADD_TABLE(file),
2463     ADD_TABLE(sr_selfreg),
2464     ADD_TABLE(sr_install_exec_seq),
2465     ADD_TABLE(media),
2466     ADD_TABLE(property)
2467 };
2468
2469 static const msi_table font_tables[] =
2470 {
2471     ADD_TABLE(font_component),
2472     ADD_TABLE(directory),
2473     ADD_TABLE(font_feature),
2474     ADD_TABLE(font_feature_comp),
2475     ADD_TABLE(font_file),
2476     ADD_TABLE(font),
2477     ADD_TABLE(font_install_exec_seq),
2478     ADD_TABLE(font_media),
2479     ADD_TABLE(property)
2480 };
2481
2482 static const msi_table vp_tables[] =
2483 {
2484     ADD_TABLE(component),
2485     ADD_TABLE(directory),
2486     ADD_TABLE(feature),
2487     ADD_TABLE(feature_comp),
2488     ADD_TABLE(file),
2489     ADD_TABLE(vp_custom_action),
2490     ADD_TABLE(vp_install_exec_seq),
2491     ADD_TABLE(media),
2492     ADD_TABLE(vp_property)
2493 };
2494
2495 static const msi_table odbc_tables[] =
2496 {
2497     ADD_TABLE(odbc_component),
2498     ADD_TABLE(directory),
2499     ADD_TABLE(odbc_feature),
2500     ADD_TABLE(odbc_feature_comp),
2501     ADD_TABLE(odbc_file),
2502     ADD_TABLE(odbc_driver),
2503     ADD_TABLE(odbc_translator),
2504     ADD_TABLE(odbc_datasource),
2505     ADD_TABLE(odbc_install_exec_seq),
2506     ADD_TABLE(odbc_media),
2507     ADD_TABLE(property)
2508 };
2509
2510 static const msi_table tl_tables[] =
2511 {
2512     ADD_TABLE(tl_component),
2513     ADD_TABLE(directory),
2514     ADD_TABLE(tl_feature),
2515     ADD_TABLE(tl_feature_comp),
2516     ADD_TABLE(tl_file),
2517     ADD_TABLE(tl_typelib),
2518     ADD_TABLE(tl_install_exec_seq),
2519     ADD_TABLE(media),
2520     ADD_TABLE(property)
2521 };
2522
2523 static const msi_table crs_tables[] =
2524 {
2525     ADD_TABLE(crs_component),
2526     ADD_TABLE(directory),
2527     ADD_TABLE(crs_feature),
2528     ADD_TABLE(crs_feature_comp),
2529     ADD_TABLE(crs_file),
2530     ADD_TABLE(crs_shortcut),
2531     ADD_TABLE(crs_install_exec_seq),
2532     ADD_TABLE(media),
2533     ADD_TABLE(property)
2534 };
2535
2536 static const msi_table pub_tables[] =
2537 {
2538     ADD_TABLE(directory),
2539     ADD_TABLE(pub_component),
2540     ADD_TABLE(pub_feature),
2541     ADD_TABLE(pub_feature_comp),
2542     ADD_TABLE(pub_file),
2543     ADD_TABLE(pub_publish_component),
2544     ADD_TABLE(pub_install_exec_seq),
2545     ADD_TABLE(media),
2546     ADD_TABLE(property)
2547 };
2548
2549 static const msi_table rd_tables[] =
2550 {
2551     ADD_TABLE(directory),
2552     ADD_TABLE(rd_component),
2553     ADD_TABLE(rd_feature),
2554     ADD_TABLE(rd_feature_comp),
2555     ADD_TABLE(rd_file),
2556     ADD_TABLE(rd_duplicate_file),
2557     ADD_TABLE(rd_install_exec_seq),
2558     ADD_TABLE(media),
2559     ADD_TABLE(property)
2560 };
2561
2562 static const msi_table rrv_tables[] =
2563 {
2564     ADD_TABLE(directory),
2565     ADD_TABLE(rrv_component),
2566     ADD_TABLE(rrv_feature),
2567     ADD_TABLE(rrv_feature_comp),
2568     ADD_TABLE(rrv_file),
2569     ADD_TABLE(rrv_registry),
2570     ADD_TABLE(rrv_remove_registry),
2571     ADD_TABLE(rrv_install_exec_seq),
2572     ADD_TABLE(media),
2573     ADD_TABLE(property)
2574 };
2575
2576 static const msi_table frp_tables[] =
2577 {
2578     ADD_TABLE(directory),
2579     ADD_TABLE(frp_component),
2580     ADD_TABLE(frp_feature),
2581     ADD_TABLE(frp_feature_comp),
2582     ADD_TABLE(frp_file),
2583     ADD_TABLE(frp_upgrade),
2584     ADD_TABLE(frp_custom_action),
2585     ADD_TABLE(frp_install_exec_seq),
2586     ADD_TABLE(media),
2587     ADD_TABLE(property)
2588 };
2589
2590 static const msi_table riv_tables[] =
2591 {
2592     ADD_TABLE(directory),
2593     ADD_TABLE(riv_component),
2594     ADD_TABLE(riv_feature),
2595     ADD_TABLE(riv_feature_comp),
2596     ADD_TABLE(riv_file),
2597     ADD_TABLE(riv_ini_file),
2598     ADD_TABLE(riv_remove_ini_file),
2599     ADD_TABLE(riv_install_exec_seq),
2600     ADD_TABLE(media),
2601     ADD_TABLE(property)
2602 };
2603
2604 static const msi_table res_tables[] =
2605 {
2606     ADD_TABLE(directory),
2607     ADD_TABLE(res_component),
2608     ADD_TABLE(res_feature),
2609     ADD_TABLE(res_feature_comp),
2610     ADD_TABLE(res_file),
2611     ADD_TABLE(res_environment),
2612     ADD_TABLE(res_install_exec_seq),
2613     ADD_TABLE(media),
2614     ADD_TABLE(property)
2615 };
2616
2617 /* cabinet definitions */
2618
2619 /* make the max size large so there is only one cab file */
2620 #define MEDIA_SIZE          0x7FFFFFFF
2621 #define FOLDER_THRESHOLD    900000
2622
2623 /* the FCI callbacks */
2624
2625 static void * CDECL mem_alloc(ULONG cb)
2626 {
2627     return HeapAlloc(GetProcessHeap(), 0, cb);
2628 }
2629
2630 static void CDECL mem_free(void *memory)
2631 {
2632     HeapFree(GetProcessHeap(), 0, memory);
2633 }
2634
2635 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
2636 {
2637     sprintf(pccab->szCab, pv, pccab->iCab);
2638     return TRUE;
2639 }
2640
2641 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
2642 {
2643     return 0;
2644 }
2645
2646 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
2647                              BOOL fContinuation, void *pv)
2648 {
2649     return 0;
2650 }
2651
2652 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
2653 {
2654     HANDLE handle;
2655     DWORD dwAccess = 0;
2656     DWORD dwShareMode = 0;
2657     DWORD dwCreateDisposition = OPEN_EXISTING;
2658     
2659     dwAccess = GENERIC_READ | GENERIC_WRITE;
2660     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
2661     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
2662
2663     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
2664         dwCreateDisposition = OPEN_EXISTING;
2665     else
2666         dwCreateDisposition = CREATE_NEW;
2667
2668     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
2669                          dwCreateDisposition, 0, NULL);
2670
2671     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
2672
2673     return (INT_PTR)handle;
2674 }
2675
2676 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2677 {
2678     HANDLE handle = (HANDLE)hf;
2679     DWORD dwRead;
2680     BOOL res;
2681     
2682     res = ReadFile(handle, memory, cb, &dwRead, NULL);
2683     ok(res, "Failed to ReadFile\n");
2684
2685     return dwRead;
2686 }
2687
2688 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2689 {
2690     HANDLE handle = (HANDLE)hf;
2691     DWORD dwWritten;
2692     BOOL res;
2693
2694     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
2695     ok(res, "Failed to WriteFile\n");
2696
2697     return dwWritten;
2698 }
2699
2700 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
2701 {
2702     HANDLE handle = (HANDLE)hf;
2703     ok(CloseHandle(handle), "Failed to CloseHandle\n");
2704
2705     return 0;
2706 }
2707
2708 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
2709 {
2710     HANDLE handle = (HANDLE)hf;
2711     DWORD ret;
2712     
2713     ret = SetFilePointer(handle, dist, NULL, seektype);
2714     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
2715
2716     return ret;
2717 }
2718
2719 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
2720 {
2721     BOOL ret = DeleteFileA(pszFile);
2722     ok(ret, "Failed to DeleteFile %s\n", pszFile);
2723
2724     return 0;
2725 }
2726
2727 static void init_functionpointers(void)
2728 {
2729     HMODULE hmsi = GetModuleHandleA("msi.dll");
2730     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
2731
2732 #define GET_PROC(mod, func) \
2733     p ## func = (void*)GetProcAddress(mod, #func); \
2734     if(!p ## func) \
2735       trace("GetProcAddress(%s) failed\n", #func);
2736
2737     GET_PROC(hmsi, MsiQueryComponentStateA);
2738     GET_PROC(hmsi, MsiSetExternalUIRecord);
2739     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
2740     GET_PROC(hmsi, MsiSourceListGetInfoA);
2741
2742     GET_PROC(hadvapi32, ConvertSidToStringSidA);
2743
2744     hsrclient = LoadLibraryA("srclient.dll");
2745     GET_PROC(hsrclient, SRRemoveRestorePoint);
2746     GET_PROC(hsrclient, SRSetRestorePointA);
2747
2748 #undef GET_PROC
2749 }
2750
2751 static BOOL check_win9x(void)
2752 {
2753     SC_HANDLE scm;
2754
2755     scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
2756     if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2757         return TRUE;
2758
2759     CloseServiceHandle(scm);
2760
2761     return FALSE;
2762 }
2763
2764 static LPSTR get_user_sid(LPSTR *usersid)
2765 {
2766     HANDLE token;
2767     BYTE buf[1024];
2768     DWORD size;
2769     PTOKEN_USER user;
2770
2771     if (!pConvertSidToStringSidA)
2772     {
2773         win_skip("ConvertSidToStringSidA is not available\n");
2774         return NULL;
2775     }
2776
2777     *usersid = NULL;
2778     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
2779     size = sizeof(buf);
2780     GetTokenInformation(token, TokenUser, buf, size, &size);
2781     user = (PTOKEN_USER)buf;
2782     pConvertSidToStringSidA(user->User.Sid, usersid);
2783     ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError());
2784     CloseHandle(token);
2785     return *usersid;
2786 }
2787
2788 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
2789 {
2790     CHAR buffer[0x20];
2791     UINT r;
2792     DWORD sz;
2793
2794     sz = sizeof buffer;
2795     r = MsiRecordGetString(rec, field, buffer, &sz);
2796     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
2797 }
2798
2799 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
2800 {
2801     LPSTR tempname;
2802
2803     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2804     GetTempFileNameA(".", "xx", 0, tempname);
2805
2806     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
2807     {
2808         lstrcpyA(pszTempName, tempname);
2809         HeapFree(GetProcessHeap(), 0, tempname);
2810         return TRUE;
2811     }
2812
2813     HeapFree(GetProcessHeap(), 0, tempname);
2814
2815     return FALSE;
2816 }
2817
2818 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
2819                                    USHORT *pattribs, int *err, void *pv)
2820 {
2821     BY_HANDLE_FILE_INFORMATION finfo;
2822     FILETIME filetime;
2823     HANDLE handle;
2824     DWORD attrs;
2825     BOOL res;
2826
2827     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
2828                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
2829
2830     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
2831
2832     res = GetFileInformationByHandle(handle, &finfo);
2833     ok(res, "Expected GetFileInformationByHandle to succeed\n");
2834    
2835     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
2836     FileTimeToDosDateTime(&filetime, pdate, ptime);
2837
2838     attrs = GetFileAttributes(pszName);
2839     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
2840
2841     return (INT_PTR)handle;
2842 }
2843
2844 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
2845 {
2846     char path[MAX_PATH];
2847     char filename[MAX_PATH];
2848
2849     lstrcpyA(path, CURR_DIR);
2850     lstrcatA(path, "\\");
2851     lstrcatA(path, file);
2852
2853     lstrcpyA(filename, file);
2854
2855     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
2856                       progress, get_open_info, compress);
2857 }
2858
2859 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
2860 {
2861     ZeroMemory(pCabParams, sizeof(CCAB));
2862
2863     pCabParams->cb = max_size;
2864     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
2865     pCabParams->setID = 0xbeef;
2866     pCabParams->iCab = 1;
2867     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
2868     lstrcatA(pCabParams->szCabPath, "\\");
2869     lstrcpyA(pCabParams->szCab, name);
2870 }
2871
2872 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
2873 {
2874     CCAB cabParams;
2875     LPCSTR ptr;
2876     HFCI hfci;
2877     ERF erf;
2878     BOOL res;
2879
2880     set_cab_parameters(&cabParams, name, max_size);
2881
2882     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2883                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2884                       get_temp_file, &cabParams, NULL);
2885
2886     ok(hfci != NULL, "Failed to create an FCI context\n");
2887
2888     ptr = files;
2889     while (*ptr)
2890     {
2891         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
2892         ok(res, "Failed to add file: %s\n", ptr);
2893         ptr += lstrlen(ptr) + 1;
2894     }
2895
2896     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2897     ok(res, "Failed to flush the cabinet\n");
2898
2899     res = FCIDestroy(hfci);
2900     ok(res, "Failed to destroy the cabinet\n");
2901 }
2902
2903 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
2904 {
2905     HKEY hkey;
2906     DWORD type, size;
2907
2908     if (RegOpenKey(HKEY_LOCAL_MACHINE,
2909                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
2910         return FALSE;
2911
2912     size = MAX_PATH;
2913     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
2914         RegCloseKey(hkey);
2915         return FALSE;
2916     }
2917
2918     size = MAX_PATH;
2919     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
2920         RegCloseKey(hkey);
2921         return FALSE;
2922     }
2923
2924     RegCloseKey(hkey);
2925     return TRUE;
2926 }
2927
2928 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
2929 {
2930     HANDLE file;
2931     DWORD written;
2932
2933     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2934     if (file == INVALID_HANDLE_VALUE)
2935         return;
2936
2937     WriteFile(file, data, strlen(data), &written, NULL);
2938
2939     if (size)
2940     {
2941         SetFilePointer(file, size, NULL, FILE_BEGIN);
2942         SetEndOfFile(file);
2943     }
2944
2945     CloseHandle(file);
2946 }
2947
2948 #define create_file(name, size) create_file_data(name, name, size)
2949
2950 static void create_test_files(void)
2951 {
2952     CreateDirectoryA("msitest", NULL);
2953     create_file("msitest\\one.txt", 100);
2954     CreateDirectoryA("msitest\\first", NULL);
2955     create_file("msitest\\first\\two.txt", 100);
2956     CreateDirectoryA("msitest\\second", NULL);
2957     create_file("msitest\\second\\three.txt", 100);
2958
2959     create_file("four.txt", 100);
2960     create_file("five.txt", 100);
2961     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
2962
2963     create_file("msitest\\filename", 100);
2964     create_file("msitest\\service.exe", 100);
2965
2966     DeleteFileA("four.txt");
2967     DeleteFileA("five.txt");
2968 }
2969
2970 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
2971 {
2972     CHAR path[MAX_PATH];
2973
2974     lstrcpyA(path, PROG_FILES_DIR);
2975     lstrcatA(path, "\\");
2976     lstrcatA(path, rel_path);
2977
2978     if (is_file)
2979         return DeleteFileA(path);
2980     else
2981         return RemoveDirectoryA(path);
2982 }
2983
2984 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
2985 {
2986     CHAR path[MAX_PATH];
2987
2988     lstrcpyA(path, COMMON_FILES_DIR);
2989     lstrcatA(path, "\\");
2990     lstrcatA(path, rel_path);
2991
2992     if (is_file)
2993         return DeleteFileA(path);
2994     else
2995         return RemoveDirectoryA(path);
2996 }
2997
2998 static void delete_test_files(void)
2999 {
3000     DeleteFileA("msitest.msi");
3001     DeleteFileA("msitest.cab");
3002     DeleteFileA("msitest\\second\\three.txt");
3003     DeleteFileA("msitest\\first\\two.txt");
3004     DeleteFileA("msitest\\one.txt");
3005     DeleteFileA("msitest\\service.exe");
3006     DeleteFileA("msitest\\filename");
3007     RemoveDirectoryA("msitest\\second");
3008     RemoveDirectoryA("msitest\\first");
3009     RemoveDirectoryA("msitest");
3010 }
3011
3012 static void write_file(const CHAR *filename, const char *data, int data_size)
3013 {
3014     DWORD size;
3015
3016     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
3017                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3018
3019     WriteFile(hf, data, data_size, &size, NULL);
3020     CloseHandle(hf);
3021 }
3022
3023 static void write_msi_summary_info(MSIHANDLE db, INT wordcount)
3024 {
3025     MSIHANDLE summary;
3026     UINT r;
3027
3028     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
3029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3030
3031     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
3032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3033
3034     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3035                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
3036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3037
3038     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3040
3041     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
3042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3043
3044     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3045     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3046
3047     /* write the summary changes back to the stream */
3048     r = MsiSummaryInfoPersist(summary);
3049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3050
3051     MsiCloseHandle(summary);
3052 }
3053
3054 #define create_database(name, tables, num_tables) \
3055     create_database_wordcount(name, tables, num_tables, 0);
3056
3057 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
3058                                       int num_tables, INT wordcount)
3059 {
3060     MSIHANDLE db;
3061     UINT r;
3062     int j;
3063
3064     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
3065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3066
3067     /* import the tables into the database */
3068     for (j = 0; j < num_tables; j++)
3069     {
3070         const msi_table *table = &tables[j];
3071
3072         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
3073
3074         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
3075         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3076
3077         DeleteFileA(table->filename);
3078     }
3079
3080     write_msi_summary_info(db, wordcount);
3081
3082     r = MsiDatabaseCommit(db);
3083     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3084
3085     MsiCloseHandle(db);
3086 }
3087
3088 static void check_service_is_installed(void)
3089 {
3090     SC_HANDLE scm, service;
3091     BOOL res;
3092
3093     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
3094     ok(scm != NULL, "Failed to open the SC Manager\n");
3095
3096     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
3097     ok(service != NULL, "Failed to open TestService\n");
3098
3099     res = DeleteService(service);
3100     ok(res, "Failed to delete TestService\n");
3101
3102     CloseServiceHandle(service);
3103     CloseServiceHandle(scm);
3104 }
3105
3106 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
3107 {
3108     RESTOREPOINTINFOA spec;
3109
3110     spec.dwEventType = event_type;
3111     spec.dwRestorePtType = APPLICATION_INSTALL;
3112     spec.llSequenceNumber = status->llSequenceNumber;
3113     lstrcpyA(spec.szDescription, "msitest restore point");
3114
3115     return pSRSetRestorePointA(&spec, status);
3116 }
3117
3118 static void remove_restore_point(DWORD seq_number)
3119 {
3120     DWORD res;
3121
3122     res = pSRRemoveRestorePoint(seq_number);
3123     if (res != ERROR_SUCCESS)
3124         trace("Failed to remove the restore point : %08x\n", res);
3125 }
3126
3127 static void test_MsiInstallProduct(void)
3128 {
3129     UINT r;
3130     CHAR path[MAX_PATH];
3131     LONG res;
3132     HKEY hkey;
3133     DWORD num, size, type;
3134
3135     if (on_win9x)
3136     {
3137         win_skip("Services are not implemented on Win9x and WinMe\n");
3138         return;
3139     }
3140
3141     /* szPackagePath is NULL */
3142     r = MsiInstallProductA(NULL, "INSTALL=ALL");
3143     ok(r == ERROR_INVALID_PARAMETER,
3144        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3145
3146     /* both szPackagePath and szCommandLine are NULL */
3147     r = MsiInstallProductA(NULL, NULL);
3148     ok(r == ERROR_INVALID_PARAMETER,
3149        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3150
3151     /* szPackagePath is empty */
3152     r = MsiInstallProductA("", "INSTALL=ALL");
3153     ok(r == ERROR_PATH_NOT_FOUND,
3154        "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
3155
3156     create_test_files();
3157     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3158
3159     /* install, don't publish */
3160     r = MsiInstallProductA(msifile, NULL);
3161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3162
3163     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3164     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3165     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3166     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3167     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3168     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3169     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3170     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3171     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3172     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3173     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3174     ok(delete_pf("msitest", FALSE), "File not installed\n");
3175
3176     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3178
3179     size = MAX_PATH;
3180     type = REG_SZ;
3181     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
3182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3183     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
3184
3185     size = MAX_PATH;
3186     type = REG_SZ;
3187     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
3188     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3189
3190     size = sizeof(num);
3191     type = REG_DWORD;
3192     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
3193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3194     ok(num == 314, "Expected 314, got %d\n", num);
3195
3196     size = MAX_PATH;
3197     type = REG_SZ;
3198     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
3199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3200     ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
3201
3202     check_service_is_installed();
3203
3204     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3205
3206     /* not published, reinstall */
3207     r = MsiInstallProductA(msifile, NULL);
3208     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3209
3210     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3211     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3212     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3213     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3214     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3215     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3216     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3217     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3218     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3219     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3220     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3221     ok(delete_pf("msitest", FALSE), "File not installed\n");
3222
3223     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3225     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3226
3227     create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table));
3228
3229     /* not published, RemovePreviousVersions set */
3230     r = MsiInstallProductA(msifile, NULL);
3231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3232
3233     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3234     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3235     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3236     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3237     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3238     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3239     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3240     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3241     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3242     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3243     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3244     ok(delete_pf("msitest", FALSE), "File not installed\n");
3245
3246     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3248     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3249
3250     create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table));
3251
3252     /* not published, version number bumped */
3253     r = MsiInstallProductA(msifile, NULL);
3254     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3255
3256     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3257     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3258     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3259     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3260     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3261     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3262     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3263     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3264     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3265     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3266     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3267     ok(delete_pf("msitest", FALSE), "File not installed\n");
3268
3269     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3270     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3271     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3272
3273     create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table));
3274
3275     /* not published, RemovePreviousVersions set and version number bumped */
3276     r = MsiInstallProductA(msifile, NULL);
3277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3278
3279     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3280     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3281     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3282     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3283     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3284     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3285     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3286     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3287     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3288     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3289     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3290     ok(delete_pf("msitest", FALSE), "File not installed\n");
3291
3292     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3294     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3295
3296     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3297
3298     /* install, publish product */
3299     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3300     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3301
3302     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3303     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3304     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3305     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3306     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3307     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3308     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3309     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3310     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3311     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3312     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3313     ok(delete_pf("msitest", FALSE), "File not installed\n");
3314
3315     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3316     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3317
3318     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3319
3320     /* published, reinstall */
3321     r = MsiInstallProductA(msifile, NULL);
3322     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3323
3324     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3325     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3326     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3327     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3328     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3329     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3330     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3331     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3332     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3333     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3334     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3335     ok(delete_pf("msitest", FALSE), "File not installed\n");
3336
3337     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3338     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3339
3340     create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table));
3341
3342     /* published product, RemovePreviousVersions set */
3343     r = MsiInstallProductA(msifile, NULL);
3344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3345
3346     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3347     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3348     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3349     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3350     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3351     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3352     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3353     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3354     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3355     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3356     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3357     ok(delete_pf("msitest", FALSE), "File not installed\n");
3358
3359     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3360     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3361
3362     create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table));
3363
3364     /* published product, version number bumped */
3365     r = MsiInstallProductA(msifile, NULL);
3366     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3367
3368     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3369     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3370     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3371     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3372     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3373     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3374     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3375     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3376     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3377     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3378     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3379     ok(delete_pf("msitest", FALSE), "File not installed\n");
3380
3381     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3382     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3383
3384     create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table));
3385
3386     /* published product, RemovePreviousVersions set and version number bumped */
3387     r = MsiInstallProductA(msifile, NULL);
3388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3389
3390     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3391     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3392     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3393     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3394     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3395     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3396     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3397     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3398     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3399     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3400     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3401     ok(delete_pf("msitest", FALSE), "File not installed\n");
3402
3403     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3404     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3405
3406     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3407     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3408
3409     delete_test_files();
3410 }
3411
3412 static void test_MsiSetComponentState(void)
3413 {
3414     INSTALLSTATE installed, action;
3415     MSIHANDLE package;
3416     char path[MAX_PATH];
3417     UINT r;
3418
3419     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3420
3421     CoInitialize(NULL);
3422
3423     lstrcpy(path, CURR_DIR);
3424     lstrcat(path, "\\");
3425     lstrcat(path, msifile);
3426
3427     r = MsiOpenPackage(path, &package);
3428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3429
3430     r = MsiDoAction(package, "CostInitialize");
3431     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3432
3433     r = MsiDoAction(package, "FileCost");
3434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3435
3436     r = MsiDoAction(package, "CostFinalize");
3437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3438
3439     r = MsiGetComponentState(package, "dangler", &installed, &action);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3441     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
3442     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
3443
3444     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
3445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3446
3447     MsiCloseHandle(package);
3448     CoUninitialize();
3449
3450     DeleteFileA(msifile);
3451 }
3452
3453 static void test_packagecoltypes(void)
3454 {
3455     MSIHANDLE hdb, view, rec;
3456     char path[MAX_PATH];
3457     LPCSTR query;
3458     UINT r, count;
3459
3460     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3461
3462     CoInitialize(NULL);
3463
3464     lstrcpy(path, CURR_DIR);
3465     lstrcat(path, "\\");
3466     lstrcat(path, msifile);
3467
3468     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
3469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3470
3471     query = "SELECT * FROM `Media`";
3472     r = MsiDatabaseOpenView( hdb, query, &view );
3473     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3474
3475     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
3476     count = MsiRecordGetFieldCount( rec );
3477     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3478     ok(count == 6, "Expected 6, got %d\n", count);
3479     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
3480     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
3481     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
3482     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
3483     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
3484     ok(check_record(rec, 6, "Source"), "wrong column label\n");
3485     MsiCloseHandle(rec);
3486
3487     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
3488     count = MsiRecordGetFieldCount( rec );
3489     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3490     ok(count == 6, "Expected 6, got %d\n", count);
3491     ok(check_record(rec, 1, "i2"), "wrong column label\n");
3492     ok(check_record(rec, 2, "i4"), "wrong column label\n");
3493     ok(check_record(rec, 3, "L64"), "wrong column label\n");
3494     ok(check_record(rec, 4, "S255"), "wrong column label\n");
3495     ok(check_record(rec, 5, "S32"), "wrong column label\n");
3496     ok(check_record(rec, 6, "S72"), "wrong column label\n");
3497
3498     MsiCloseHandle(rec);
3499     MsiCloseHandle(view);
3500     MsiCloseHandle(hdb);
3501     CoUninitialize();
3502
3503     DeleteFile(msifile);
3504 }
3505
3506 static void create_cc_test_files(void)
3507 {
3508     CCAB cabParams;
3509     HFCI hfci;
3510     ERF erf;
3511     static CHAR cab_context[] = "test%d.cab";
3512     BOOL res;
3513
3514     create_file("maximus", 500);
3515     create_file("augustus", 50000);
3516     create_file("tiberius", 500);
3517     create_file("caesar", 500);
3518
3519     set_cab_parameters(&cabParams, "test1.cab", 40000);
3520
3521     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
3522                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
3523                       get_temp_file, &cabParams, cab_context);
3524     ok(hfci != NULL, "Failed to create an FCI context\n");
3525
3526     res = add_file(hfci, "maximus", tcompTYPE_NONE);
3527     ok(res, "Failed to add file maximus\n");
3528
3529     res = add_file(hfci, "augustus", tcompTYPE_NONE);
3530     ok(res, "Failed to add file augustus\n");
3531
3532     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
3533     ok(res, "Failed to add file tiberius\n");
3534
3535     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
3536     ok(res, "Failed to flush the cabinet\n");
3537
3538     res = FCIDestroy(hfci);
3539     ok(res, "Failed to destroy the cabinet\n");
3540
3541     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3542
3543     DeleteFile("maximus");
3544     DeleteFile("augustus");
3545     DeleteFile("tiberius");
3546     DeleteFile("caesar");
3547 }
3548
3549 static void delete_cab_files(void)
3550 {
3551     SHFILEOPSTRUCT shfl;
3552     CHAR path[MAX_PATH+10];
3553
3554     lstrcpyA(path, CURR_DIR);
3555     lstrcatA(path, "\\*.cab");
3556     path[strlen(path) + 1] = '\0';
3557
3558     shfl.hwnd = NULL;
3559     shfl.wFunc = FO_DELETE;
3560     shfl.pFrom = path;
3561     shfl.pTo = NULL;
3562     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
3563
3564     SHFileOperation(&shfl);
3565 }
3566
3567 static void test_continuouscabs(void)
3568 {
3569     UINT r;
3570
3571     create_cc_test_files();
3572     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3573
3574     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3575
3576     r = MsiInstallProductA(msifile, NULL);
3577     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3578     {
3579         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3580         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3581         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3582         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3583         ok(delete_pf("msitest", FALSE), "File not installed\n");
3584     }
3585
3586     delete_cab_files();
3587     DeleteFile(msifile);
3588
3589     create_cc_test_files();
3590     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
3591
3592     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3593
3594     r = MsiInstallProductA(msifile, NULL);
3595     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3596     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3597     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3598     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
3599     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3600     ok(delete_pf("msitest", FALSE), "File not installed\n");
3601
3602     delete_cab_files();
3603     DeleteFile(msifile);
3604 }
3605
3606 static void test_caborder(void)
3607 {
3608     UINT r;
3609
3610     create_file("imperator", 100);
3611     create_file("maximus", 500);
3612     create_file("augustus", 50000);
3613     create_file("caesar", 500);
3614
3615     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3616
3617     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3618
3619     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3620     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3621     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3622
3623     r = MsiInstallProductA(msifile, NULL);
3624     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3625     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3626     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3627     todo_wine
3628     {
3629         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3630         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3631     }
3632
3633     delete_cab_files();
3634
3635     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
3636     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
3637     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3638
3639     r = MsiInstallProductA(msifile, NULL);
3640     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3641     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3642     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3643     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3644     todo_wine
3645     {
3646         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3647     }
3648
3649     delete_cab_files();
3650     DeleteFile(msifile);
3651
3652     create_cc_test_files();
3653     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
3654
3655     r = MsiInstallProductA(msifile, NULL);
3656     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3657     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3658     ok(!delete_pf("msitest", FALSE), "File is installed\n");
3659     todo_wine
3660     {
3661         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3662         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3663     }
3664
3665     delete_cab_files();
3666     DeleteFile(msifile);
3667
3668     create_cc_test_files();
3669     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
3670
3671     r = MsiInstallProductA(msifile, NULL);
3672     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3673     todo_wine
3674     {
3675         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3676         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3677         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3678         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3679     }
3680
3681     delete_cab_files();
3682     DeleteFile("imperator");
3683     DeleteFile("maximus");
3684     DeleteFile("augustus");
3685     DeleteFile("caesar");
3686     DeleteFile(msifile);
3687 }
3688
3689 static void test_mixedmedia(void)
3690 {
3691     UINT r;
3692
3693     CreateDirectoryA("msitest", NULL);
3694     create_file("msitest\\maximus", 500);
3695     create_file("msitest\\augustus", 500);
3696     create_file("caesar", 500);
3697
3698     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
3699
3700     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3701
3702     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
3703
3704     r = MsiInstallProductA(msifile, NULL);
3705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3706     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3707     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3708     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3709     ok(delete_pf("msitest", FALSE), "File not installed\n");
3710
3711     /* Delete the files in the temp (current) folder */
3712     DeleteFile("msitest\\maximus");
3713     DeleteFile("msitest\\augustus");
3714     RemoveDirectory("msitest");
3715     DeleteFile("caesar");
3716     DeleteFile("test1.cab");
3717     DeleteFile(msifile);
3718 }
3719
3720 static void test_samesequence(void)
3721 {
3722     UINT r;
3723
3724     create_cc_test_files();
3725     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
3726
3727     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3728
3729     r = MsiInstallProductA(msifile, NULL);
3730     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3731     {
3732         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3733         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3734         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3735         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3736         ok(delete_pf("msitest", FALSE), "File not installed\n");
3737     }
3738
3739     delete_cab_files();
3740     DeleteFile(msifile);
3741 }
3742
3743 static void test_uiLevelFlags(void)
3744 {
3745     UINT r;
3746
3747     create_cc_test_files();
3748     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
3749
3750     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
3751
3752     r = MsiInstallProductA(msifile, NULL);
3753     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3754     {
3755         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3756         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
3757         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3758         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3759         ok(delete_pf("msitest", FALSE), "File not installed\n");
3760     }
3761
3762     delete_cab_files();
3763     DeleteFile(msifile);
3764 }
3765
3766 static BOOL file_matches(LPSTR path)
3767 {
3768     CHAR buf[MAX_PATH];
3769     HANDLE file;
3770     DWORD size;
3771
3772     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3773                       NULL, OPEN_EXISTING, 0, NULL);
3774
3775     ZeroMemory(buf, MAX_PATH);
3776     ReadFile(file, buf, 15, &size, NULL);
3777     CloseHandle(file);
3778
3779     return !lstrcmp(buf, "msitest\\maximus");
3780 }
3781
3782 static void test_readonlyfile(void)
3783 {
3784     UINT r;
3785     DWORD size;
3786     HANDLE file;
3787     CHAR path[MAX_PATH];
3788
3789     CreateDirectoryA("msitest", NULL);
3790     create_file("msitest\\maximus", 500);
3791     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
3792
3793     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3794
3795     lstrcpy(path, PROG_FILES_DIR);
3796     lstrcat(path, "\\msitest");
3797     CreateDirectory(path, NULL);
3798
3799     lstrcat(path, "\\maximus");
3800     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3801                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3802
3803     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3804     CloseHandle(file);
3805
3806     r = MsiInstallProductA(msifile, NULL);
3807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3808     ok(file_matches(path), "Expected file to be overwritten\n");
3809     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3810     ok(delete_pf("msitest", FALSE), "File not installed\n");
3811
3812     /* Delete the files in the temp (current) folder */
3813     DeleteFile("msitest\\maximus");
3814     RemoveDirectory("msitest");
3815     DeleteFile(msifile);
3816 }
3817
3818 static void test_readonlyfile_cab(void)
3819 {
3820     UINT r;
3821     DWORD size;
3822     HANDLE file;
3823     CHAR path[MAX_PATH];
3824     CHAR buf[16];
3825
3826     CreateDirectoryA("msitest", NULL);
3827     create_file("maximus", 500);
3828     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3829     DeleteFile("maximus");
3830
3831     create_database(msifile, rofc_tables, sizeof(rofc_tables) / sizeof(msi_table));
3832
3833     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3834
3835     lstrcpy(path, PROG_FILES_DIR);
3836     lstrcat(path, "\\msitest");
3837     CreateDirectory(path, NULL);
3838
3839     lstrcat(path, "\\maximus");
3840     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3841                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3842
3843     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3844     CloseHandle(file);
3845
3846     r = MsiInstallProductA(msifile, NULL);
3847     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3848
3849     memset( buf, 0, sizeof(buf) );
3850     if ((file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3851                            NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
3852     {
3853         ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
3854         CloseHandle(file);
3855     }
3856     ok(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "Expected file to be overwritten, got '%s'\n", buf);
3857     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3858     ok(delete_pf("msitest", FALSE), "File not installed\n");
3859
3860     /* Delete the files in the temp (current) folder */
3861     delete_cab_files();
3862     DeleteFile("msitest\\maximus");
3863     RemoveDirectory("msitest");
3864     DeleteFile(msifile);
3865 }
3866
3867 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
3868 {
3869     WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
3870     IStorage *stg;
3871     IStream *stm;
3872     HRESULT hr;
3873     HANDLE handle;
3874
3875     MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
3876     hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
3877     if (FAILED(hr))
3878         return FALSE;
3879
3880     MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
3881     hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3882     if (FAILED(hr))
3883     {
3884         IStorage_Release(stg);
3885         return FALSE;
3886     }
3887
3888     handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
3889     if (handle != INVALID_HANDLE_VALUE)
3890     {
3891         DWORD count;
3892         char buffer[1024];
3893         if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
3894             IStream_Write(stm, buffer, count, &count);
3895         CloseHandle(handle);
3896     }
3897
3898     IStream_Release(stm);
3899     IStorage_Release(stg);
3900
3901     return TRUE;
3902 }
3903
3904 static void test_lastusedsource(void)
3905 {
3906     static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3907
3908     UINT r;
3909     char value[MAX_PATH], path[MAX_PATH];
3910     DWORD size;
3911
3912     if (!pMsiSourceListGetInfoA)
3913     {
3914         win_skip("MsiSourceListGetInfoA is not available\n");
3915         return;
3916     }
3917
3918     CreateDirectoryA("msitest", NULL);
3919     create_file("maximus", 500);
3920     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3921     DeleteFile("maximus");
3922
3923     create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
3924     create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
3925     create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
3926
3927     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3928
3929     /* no cabinet file */
3930
3931     size = MAX_PATH;
3932     lstrcpyA(value, "aaa");
3933     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3934                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3935     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3936     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3937
3938     r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
3939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3940
3941     lstrcpyA(path, CURR_DIR);
3942     lstrcatA(path, "\\");
3943
3944     size = MAX_PATH;
3945     lstrcpyA(value, "aaa");
3946     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3947                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3949     todo_wine
3950     {
3951     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3952     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3953     }
3954
3955     r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
3956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3957
3958     /* separate cabinet file */
3959
3960     size = MAX_PATH;
3961     lstrcpyA(value, "aaa");
3962     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3963                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3964     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3965     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3966
3967     r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
3968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3969
3970     lstrcpyA(path, CURR_DIR);
3971     lstrcatA(path, "\\");
3972
3973     size = MAX_PATH;
3974     lstrcpyA(value, "aaa");
3975     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3976                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3978     todo_wine
3979     {
3980     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3981     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3982     }
3983
3984     r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
3985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3986
3987     size = MAX_PATH;
3988     lstrcpyA(value, "aaa");
3989     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3990                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3991     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3992     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3993
3994     /* embedded cabinet stream */
3995
3996     add_cabinet_storage("msifile2.msi", "test1.cab");
3997
3998     r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
3999     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4000
4001     size = MAX_PATH;
4002     lstrcpyA(value, "aaa");
4003     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4004                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4005     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4006     todo_wine
4007     {
4008     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4009     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4010     }
4011
4012     r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
4013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4014
4015     size = MAX_PATH;
4016     lstrcpyA(value, "aaa");
4017     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4018                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4019     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4020     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4021
4022     /* Delete the files in the temp (current) folder */
4023     delete_cab_files();
4024     DeleteFile("msitest\\maximus");
4025     RemoveDirectory("msitest");
4026     DeleteFile("msifile0.msi");
4027     DeleteFile("msifile1.msi");
4028     DeleteFile("msifile2.msi");
4029 }
4030
4031 static void test_setdirproperty(void)
4032 {
4033     UINT r;
4034
4035     CreateDirectoryA("msitest", NULL);
4036     create_file("msitest\\maximus", 500);
4037     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
4038
4039     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4040
4041     r = MsiInstallProductA(msifile, NULL);
4042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4043     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
4044     ok(delete_cf("msitest", FALSE), "File not installed\n");
4045
4046     /* Delete the files in the temp (current) folder */
4047     DeleteFile(msifile);
4048     DeleteFile("msitest\\maximus");
4049     RemoveDirectory("msitest");
4050 }
4051
4052 static void test_cabisextracted(void)
4053 {
4054     UINT r;
4055
4056     CreateDirectoryA("msitest", NULL);
4057     create_file("msitest\\gaius", 500);
4058     create_file("maximus", 500);
4059     create_file("augustus", 500);
4060     create_file("caesar", 500);
4061
4062     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4063     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
4064     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
4065
4066     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
4067
4068     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4069
4070     r = MsiInstallProductA(msifile, NULL);
4071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4072     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4073     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4074     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4075     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
4076     ok(delete_pf("msitest", FALSE), "File not installed\n");
4077
4078     /* Delete the files in the temp (current) folder */
4079     delete_cab_files();
4080     DeleteFile(msifile);
4081     DeleteFile("maximus");
4082     DeleteFile("augustus");
4083     DeleteFile("caesar");
4084     DeleteFile("msitest\\gaius");
4085     RemoveDirectory("msitest");
4086 }
4087
4088 static void test_concurrentinstall(void)
4089 {
4090     UINT r;
4091     CHAR path[MAX_PATH];
4092
4093     CreateDirectoryA("msitest", NULL);
4094     CreateDirectoryA("msitest\\msitest", NULL);
4095     create_file("msitest\\maximus", 500);
4096     create_file("msitest\\msitest\\augustus", 500);
4097
4098     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
4099
4100     lstrcpyA(path, CURR_DIR);
4101     lstrcatA(path, "\\msitest\\concurrent.msi");
4102     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
4103
4104     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4105
4106     r = MsiInstallProductA(msifile, NULL);
4107     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4108     if (!delete_pf("msitest\\augustus", TRUE))
4109         trace("concurrent installs not supported\n");
4110     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4111     ok(delete_pf("msitest", FALSE), "File not installed\n");
4112
4113     DeleteFile(path);
4114
4115     r = MsiInstallProductA(msifile, NULL);
4116     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4117     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4118     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4119     ok(delete_pf("msitest", FALSE), "File not installed\n");
4120
4121     DeleteFile(msifile);
4122     DeleteFile("msitest\\msitest\\augustus");
4123     DeleteFile("msitest\\maximus");
4124     RemoveDirectory("msitest\\msitest");
4125     RemoveDirectory("msitest");
4126 }
4127
4128 static void test_setpropertyfolder(void)
4129 {
4130     UINT r;
4131     CHAR path[MAX_PATH];
4132     DWORD attr;
4133
4134     lstrcpyA(path, PROG_FILES_DIR);
4135     lstrcatA(path, "\\msitest\\added");
4136
4137     CreateDirectoryA("msitest", NULL);
4138     create_file("msitest\\maximus", 500);
4139
4140     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
4141
4142     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4143
4144     r = MsiInstallProductA(msifile, NULL);
4145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4146     attr = GetFileAttributesA(path);
4147     if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
4148     {
4149         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
4150         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
4151         ok(delete_pf("msitest", FALSE), "File not installed\n");
4152     }
4153     else
4154     {
4155         trace("changing folder property not supported\n");
4156         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4157         ok(delete_pf("msitest", FALSE), "File not installed\n");
4158     }
4159
4160     /* Delete the files in the temp (current) folder */
4161     DeleteFile(msifile);
4162     DeleteFile("msitest\\maximus");
4163     RemoveDirectory("msitest");
4164 }
4165
4166 static BOOL file_exists(LPCSTR file)
4167 {
4168     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
4169 }
4170
4171 static BOOL pf_exists(LPCSTR file)
4172 {
4173     CHAR path[MAX_PATH];
4174
4175     lstrcpyA(path, PROG_FILES_DIR);
4176     lstrcatA(path, "\\");
4177     lstrcatA(path, file);
4178
4179     return file_exists(path);
4180 }
4181
4182 static void delete_pfmsitest_files(void)
4183 {
4184     SHFILEOPSTRUCT shfl;
4185     CHAR path[MAX_PATH+11];
4186
4187     lstrcpyA(path, PROG_FILES_DIR);
4188     lstrcatA(path, "\\msitest\\*");
4189     path[strlen(path) + 1] = '\0';
4190
4191     shfl.hwnd = NULL;
4192     shfl.wFunc = FO_DELETE;
4193     shfl.pFrom = path;
4194     shfl.pTo = NULL;
4195     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
4196
4197     SHFileOperation(&shfl);
4198
4199     lstrcpyA(path, PROG_FILES_DIR);
4200     lstrcatA(path, "\\msitest");
4201     RemoveDirectoryA(path);
4202 }
4203
4204 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
4205 {
4206     char val[MAX_PATH];
4207     DWORD size, type;
4208     LONG res;
4209
4210     size = MAX_PATH;
4211     val[0] = '\0';
4212     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
4213
4214     if (res != ERROR_SUCCESS ||
4215         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
4216     {
4217         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4218         return;
4219     }
4220
4221     if (!expected)
4222         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
4223     else
4224     {
4225         if (bcase)
4226             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
4227         else
4228             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
4229     }
4230 }
4231
4232 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
4233 {
4234     DWORD val, size, type;
4235     LONG res;
4236
4237     size = sizeof(DWORD);
4238     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4239
4240     if (res != ERROR_SUCCESS || type != REG_DWORD)
4241     {
4242         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4243         return;
4244     }
4245
4246     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
4247 }
4248
4249 static void check_reg_dword2(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD line)
4250 {
4251     DWORD val, size, type;
4252     LONG res;
4253
4254     size = sizeof(DWORD);
4255     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4256
4257     if (res != ERROR_SUCCESS || type != REG_DWORD)
4258     {
4259         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4260         return;
4261     }
4262
4263     ok_(__FILE__, line)(val == expected1 || val == expected2, "Expected %d or %d, got %d\n", expected1, expected2, val);
4264 }
4265
4266 static void check_reg_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line)
4267 {
4268     DWORD val, size, type;
4269     LONG res;
4270
4271     size = sizeof(DWORD);
4272     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4273
4274     if (res != ERROR_SUCCESS || type != REG_DWORD)
4275     {
4276         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4277         return;
4278     }
4279
4280     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3,
4281                         "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val);
4282 }
4283
4284 #define CHECK_REG_STR(prodkey, name, expected) \
4285     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
4286
4287 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
4288     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
4289     RegDeleteValueA(prodkey, name);
4290
4291 #define CHECK_REG_ISTR(prodkey, name, expected) \
4292     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
4293
4294 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
4295     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
4296     RegDeleteValueA(prodkey, name);
4297
4298 #define CHECK_REG_DWORD(prodkey, name, expected) \
4299     check_reg_dword(prodkey, name, expected, __LINE__);
4300
4301 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
4302     check_reg_dword(prodkey, name, expected, __LINE__); \
4303     RegDeleteValueA(prodkey, name);
4304
4305 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
4306     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
4307
4308 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
4309     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
4310     RegDeleteValueA(prodkey, name);
4311
4312 #define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4313     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__);
4314
4315 #define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4316     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \
4317     RegDeleteValueA(prodkey, name);
4318
4319 static void get_date_str(LPSTR date)
4320 {
4321     SYSTEMTIME systime;
4322
4323     static const char date_fmt[] = "%d%02d%02d";
4324     GetLocalTime(&systime);
4325     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
4326 }
4327
4328 static void test_publish_registerproduct(void)
4329 {
4330     UINT r;
4331     LONG res;
4332     HKEY hkey;
4333     HKEY props, usage;
4334     LPSTR usersid;
4335     char date[MAX_PATH];
4336     char temp[MAX_PATH];
4337     char keypath[MAX_PATH];
4338
4339     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4340                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4341     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4342                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4343     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4344                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4345     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4346                                     "\\51AAE0C44620A5E4788506E91F249BD2";
4347
4348     if (!get_user_sid(&usersid))
4349         return;
4350
4351     get_date_str(date);
4352     GetTempPath(MAX_PATH, temp);
4353
4354     CreateDirectoryA("msitest", NULL);
4355     create_file("msitest\\maximus", 500);
4356
4357     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4358
4359     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4360
4361     /* RegisterProduct */
4362     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4364     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4365     ok(delete_pf("msitest", FALSE), "File not installed\n");
4366
4367     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
4368     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4369
4370     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4372
4373     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4374     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4375     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4376     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4377     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4378     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4379     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4380     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4381     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4382     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4383     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4384     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4385     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4386     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4387     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4388     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4389     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4390     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4391     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4392     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4393     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4394     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4395     todo_wine
4396     {
4397         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4398     }
4399
4400     RegDeleteKeyA(hkey, "");
4401     RegCloseKey(hkey);
4402
4403     sprintf(keypath, userdata, usersid);
4404     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4406
4407     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4409
4410     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4411     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4412     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4413     CHECK_DEL_REG_STR(props, "InstallDate", date);
4414     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4415     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4416     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4417     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4418     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4419     CHECK_DEL_REG_STR(props, "Comments", NULL);
4420     CHECK_DEL_REG_STR(props, "Contact", NULL);
4421     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4422     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4423     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4424     CHECK_DEL_REG_STR(props, "Readme", NULL);
4425     CHECK_DEL_REG_STR(props, "Size", NULL);
4426     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4427     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4428     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4429     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4430     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4431     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4432     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4433     todo_wine
4434     {
4435         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4436     }
4437
4438     RegDeleteKeyA(props, "");
4439     RegCloseKey(props);
4440
4441     res = RegOpenKeyA(hkey, "Usage", &usage);
4442     todo_wine
4443     {
4444         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4445     }
4446
4447     RegDeleteKeyA(usage, "");
4448     RegCloseKey(usage);
4449     RegDeleteKeyA(hkey, "");
4450     RegCloseKey(hkey);
4451
4452     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4454
4455     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4456
4457     RegDeleteKeyA(hkey, "");
4458     RegCloseKey(hkey);
4459
4460     /* RegisterProduct, machine */
4461     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
4462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4463     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4464     ok(delete_pf("msitest", FALSE), "File not installed\n");
4465
4466     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
4467     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4468
4469     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4471
4472     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4473     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4474     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4475     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4476     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4477     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4478     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4479     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4480     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4481     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4482     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4483     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4484     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4485     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4486     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4487     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4488     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4489     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4490     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4491     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4492     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4493     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4494     todo_wine
4495     {
4496         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4497     }
4498
4499     RegDeleteKeyA(hkey, "");
4500     RegCloseKey(hkey);
4501
4502     sprintf(keypath, userdata, "S-1-5-18");
4503     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4504     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4505
4506     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4508
4509     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4510     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4511     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4512     CHECK_DEL_REG_STR(props, "InstallDate", date);
4513     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4514     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4515     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4516     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4517     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4518     CHECK_DEL_REG_STR(props, "Comments", NULL);
4519     CHECK_DEL_REG_STR(props, "Contact", NULL);
4520     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4521     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4522     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4523     CHECK_DEL_REG_STR(props, "Readme", NULL);
4524     CHECK_DEL_REG_STR(props, "Size", NULL);
4525     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4526     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4527     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4528     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4529     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4530     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4531     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4532     todo_wine
4533     {
4534         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4535     }
4536
4537     RegDeleteKeyA(props, "");
4538     RegCloseKey(props);
4539
4540     res = RegOpenKeyA(hkey, "Usage", &usage);
4541     todo_wine
4542     {
4543         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4544     }
4545
4546     RegDeleteKeyA(usage, "");
4547     RegCloseKey(usage);
4548     RegDeleteKeyA(hkey, "");
4549     RegCloseKey(hkey);
4550
4551     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4553
4554     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4555
4556     RegDeleteKeyA(hkey, "");
4557     RegCloseKey(hkey);
4558
4559     DeleteFile(msifile);
4560     DeleteFile("msitest\\maximus");
4561     RemoveDirectory("msitest");
4562     HeapFree(GetProcessHeap(), 0, usersid);
4563 }
4564
4565 static void test_publish_publishproduct(void)
4566 {
4567     UINT r;
4568     LONG res;
4569     LPSTR usersid;
4570     HKEY sourcelist, net, props;
4571     HKEY hkey, patches, media;
4572     CHAR keypath[MAX_PATH];
4573     CHAR temp[MAX_PATH];
4574     CHAR path[MAX_PATH];
4575
4576     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4577                                    "\\Installer\\UserData\\%s\\Products"
4578                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4579     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
4580                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4581     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4582                                      "\\51AAE0C44620A5E4788506E91F249BD2";
4583     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4584                                   "\\Installer\\Products"
4585                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4586     static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4587     static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4588
4589     if (!get_user_sid(&usersid))
4590         return;
4591
4592     GetTempPath(MAX_PATH, temp);
4593
4594     CreateDirectoryA("msitest", NULL);
4595     create_file("msitest\\maximus", 500);
4596
4597     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4598
4599     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4600
4601     /* PublishProduct, current user */
4602     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4603     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4604     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4605     ok(delete_pf("msitest", FALSE), "File not installed\n");
4606
4607     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4608     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4609
4610     sprintf(keypath, prodpath, usersid);
4611     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4613
4614     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4615     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4616
4617     res = RegOpenKeyA(hkey, "Patches", &patches);
4618     todo_wine
4619     {
4620         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4621
4622         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4623     }
4624
4625     RegDeleteKeyA(patches, "");
4626     RegCloseKey(patches);
4627     RegDeleteKeyA(hkey, "");
4628     RegCloseKey(hkey);
4629
4630     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4631     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4632
4633     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4634     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4635     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4636     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4637     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4638     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
4639     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4640     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4641     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4642
4643     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
4644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4645
4646     lstrcpyA(path, "n;1;");
4647     lstrcatA(path, temp);
4648     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
4649     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
4650
4651     res = RegOpenKeyA(sourcelist, "Net", &net);
4652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4653
4654     CHECK_DEL_REG_STR(net, "1", temp);
4655
4656     RegDeleteKeyA(net, "");
4657     RegCloseKey(net);
4658
4659     res = RegOpenKeyA(sourcelist, "Media", &media);
4660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4661
4662     CHECK_DEL_REG_STR(media, "1", "DISK1;");
4663
4664     RegDeleteKeyA(media, "");
4665     RegCloseKey(media);
4666     RegDeleteKeyA(sourcelist, "");
4667     RegCloseKey(sourcelist);
4668     RegDeleteKeyA(hkey, "");
4669     RegCloseKey(hkey);
4670
4671     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
4672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4673
4674     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4675
4676     RegDeleteKeyA(hkey, "");
4677     RegCloseKey(hkey);
4678
4679     /* PublishProduct, machine */
4680     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
4681     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4682     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4683     ok(delete_pf("msitest", FALSE), "File not installed\n");
4684
4685     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4686     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4687
4688     sprintf(keypath, prodpath, "S-1-5-18");
4689     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4690     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4691
4692     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4693     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4694
4695     res = RegOpenKeyA(hkey, "Patches", &patches);
4696     todo_wine
4697     {
4698         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4699
4700         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4701     }
4702
4703     RegDeleteKeyA(patches, "");
4704     RegCloseKey(patches);
4705     RegDeleteKeyA(hkey, "");
4706     RegCloseKey(hkey);
4707
4708     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
4709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4710
4711     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4712     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4713     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4714     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4715     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4716     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
4717     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4718     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4719     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4720
4721     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
4722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4723
4724     lstrcpyA(path, "n;1;");
4725     lstrcatA(path, temp);
4726     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
4727     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
4728
4729     res = RegOpenKeyA(sourcelist, "Net", &net);
4730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4731
4732     CHECK_DEL_REG_STR(net, "1", temp);
4733
4734     RegDeleteKeyA(net, "");
4735     RegCloseKey(net);
4736
4737     res = RegOpenKeyA(sourcelist, "Media", &media);
4738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4739
4740     CHECK_DEL_REG_STR(media, "1", "DISK1;");
4741
4742     RegDeleteKeyA(media, "");
4743     RegCloseKey(media);
4744     RegDeleteKeyA(sourcelist, "");
4745     RegCloseKey(sourcelist);
4746     RegDeleteKeyA(hkey, "");
4747     RegCloseKey(hkey);
4748
4749     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
4750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4751
4752     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4753
4754     RegDeleteKeyA(hkey, "");
4755     RegCloseKey(hkey);
4756
4757     DeleteFile(msifile);
4758     DeleteFile("msitest\\maximus");
4759     RemoveDirectory("msitest");
4760     HeapFree(GetProcessHeap(), 0, usersid);
4761 }
4762
4763 static void test_publish_publishfeatures(void)
4764 {
4765     UINT r;
4766     LONG res;
4767     HKEY hkey;
4768     LPSTR usersid;
4769     CHAR keypath[MAX_PATH];
4770
4771     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
4772                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4773     static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4774                                  "\\Installer\\UserData\\%s\\Products"
4775                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
4776     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4777                                   "\\Installer\\Features";
4778     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
4779                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4780
4781     if (!get_user_sid(&usersid))
4782         return;
4783
4784     CreateDirectoryA("msitest", NULL);
4785     create_file("msitest\\maximus", 500);
4786
4787     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4788
4789     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4790
4791     /* PublishFeatures, current user */
4792     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4794     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4795     ok(delete_pf("msitest", FALSE), "File not installed\n");
4796
4797     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
4798     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4799
4800     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
4801     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4802
4803     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
4804     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4805
4806     CHECK_REG_STR(hkey, "feature", "");
4807     CHECK_REG_STR(hkey, "montecristo", "");
4808
4809     RegDeleteValueA(hkey, "feature");
4810     RegDeleteValueA(hkey, "montecristo");
4811     RegDeleteKeyA(hkey, "");
4812     RegCloseKey(hkey);
4813
4814     sprintf(keypath, udpath, usersid);
4815     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4816     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4817
4818     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
4819     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
4820
4821     RegDeleteValueA(hkey, "feature");
4822     RegDeleteValueA(hkey, "montecristo");
4823     RegDeleteKeyA(hkey, "");
4824     RegCloseKey(hkey);
4825
4826     /* PublishFeatures, machine */
4827     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
4828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4829     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4830     ok(delete_pf("msitest", FALSE), "File not installed\n");
4831
4832     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
4833     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4834
4835     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
4836     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4837
4838     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
4839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4840
4841     CHECK_REG_STR(hkey, "feature", "");
4842     CHECK_REG_STR(hkey, "montecristo", "");
4843
4844     RegDeleteValueA(hkey, "feature");
4845     RegDeleteValueA(hkey, "montecristo");
4846     RegDeleteKeyA(hkey, "");
4847     RegCloseKey(hkey);
4848
4849     sprintf(keypath, udpath, "S-1-5-18");
4850     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4852
4853     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
4854     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
4855
4856     RegDeleteValueA(hkey, "feature");
4857     RegDeleteValueA(hkey, "montecristo");
4858     RegDeleteKeyA(hkey, "");
4859     RegCloseKey(hkey);
4860
4861     DeleteFile(msifile);
4862     DeleteFile("msitest\\maximus");
4863     RemoveDirectory("msitest");
4864     HeapFree(GetProcessHeap(), 0, usersid);
4865 }
4866
4867 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
4868 {
4869     DWORD len = 0;
4870     LPSTR val;
4871     LONG r;
4872
4873     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
4874     if (r != ERROR_SUCCESS)
4875         return NULL;
4876
4877     len += sizeof (WCHAR);
4878     val = HeapAlloc(GetProcessHeap(), 0, len);
4879     if (!val) return NULL;
4880     val[0] = 0;
4881     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
4882     return val;
4883 }
4884
4885 static void get_owner_company(LPSTR *owner, LPSTR *company)
4886 {
4887     LONG res;
4888     HKEY hkey;
4889
4890     *owner = *company = NULL;
4891
4892     res = RegOpenKeyA(HKEY_CURRENT_USER,
4893                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
4894     if (res == ERROR_SUCCESS)
4895     {
4896         *owner = reg_get_val_str(hkey, "DefName");
4897         *company = reg_get_val_str(hkey, "DefCompany");
4898         RegCloseKey(hkey);
4899     }
4900
4901     if (!*owner || !*company)
4902     {
4903         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
4904                           "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
4905         if (res == ERROR_SUCCESS)
4906         {
4907             *owner = reg_get_val_str(hkey, "RegisteredOwner");
4908             *company = reg_get_val_str(hkey, "RegisteredOrganization");
4909             RegCloseKey(hkey);
4910         }
4911     }
4912
4913     if (!*owner || !*company)
4914     {
4915         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
4916                           "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
4917         if (res == ERROR_SUCCESS)
4918         {
4919             *owner = reg_get_val_str(hkey, "RegisteredOwner");
4920             *company = reg_get_val_str(hkey, "RegisteredOrganization");
4921             RegCloseKey(hkey);
4922         }
4923     }
4924 }
4925
4926 static void test_publish_registeruser(void)
4927 {
4928     UINT r;
4929     LONG res;
4930     HKEY props;
4931     LPSTR usersid;
4932     LPSTR owner, company;
4933     CHAR keypath[MAX_PATH];
4934
4935     static const CHAR keyfmt[] =
4936         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
4937         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
4938
4939     if (!get_user_sid(&usersid))
4940         return;
4941
4942     get_owner_company(&owner, &company);
4943
4944     CreateDirectoryA("msitest", NULL);
4945     create_file("msitest\\maximus", 500);
4946
4947     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4948
4949     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4950
4951     /* RegisterUser, per-user */
4952     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
4953     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4954     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4955     ok(delete_pf("msitest", FALSE), "File not installed\n");
4956
4957     sprintf(keypath, keyfmt, usersid);
4958
4959     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
4960     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4961
4962     CHECK_REG_STR(props, "ProductID", "none");
4963     CHECK_REG_STR(props, "RegCompany", company);
4964     CHECK_REG_STR(props, "RegOwner", owner);
4965
4966     RegDeleteValueA(props, "ProductID");
4967     RegDeleteValueA(props, "RegCompany");
4968     RegDeleteValueA(props, "RegOwner");
4969     RegDeleteKeyA(props, "");
4970     RegCloseKey(props);
4971
4972     /* RegisterUser, machine */
4973     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
4974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4975     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4976     ok(delete_pf("msitest", FALSE), "File not installed\n");
4977
4978     sprintf(keypath, keyfmt, "S-1-5-18");
4979
4980     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
4981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4982
4983     CHECK_REG_STR(props, "ProductID", "none");
4984     CHECK_REG_STR(props, "RegCompany", company);
4985     CHECK_REG_STR(props, "RegOwner", owner);
4986
4987     RegDeleteValueA(props, "ProductID");
4988     RegDeleteValueA(props, "RegCompany");
4989     RegDeleteValueA(props, "RegOwner");
4990     RegDeleteKeyA(props, "");
4991     RegCloseKey(props);
4992
4993     HeapFree(GetProcessHeap(), 0, company);
4994     HeapFree(GetProcessHeap(), 0, owner);
4995
4996     DeleteFile(msifile);
4997     DeleteFile("msitest\\maximus");
4998     RemoveDirectory("msitest");
4999     LocalFree(usersid);
5000 }
5001
5002 static void test_publish_processcomponents(void)
5003 {
5004     UINT r;
5005     LONG res;
5006     DWORD size;
5007     HKEY comp, hkey;
5008     LPSTR usersid;
5009     CHAR val[MAX_PATH];
5010     CHAR keypath[MAX_PATH];
5011     CHAR program_files_maximus[MAX_PATH];
5012
5013     static const CHAR keyfmt[] =
5014         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
5015         "UserData\\%s\\Components\\%s";
5016     static const CHAR compkey[] =
5017         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
5018
5019     if (!get_user_sid(&usersid))
5020         return;
5021
5022     CreateDirectoryA("msitest", NULL);
5023     create_file("msitest\\maximus", 500);
5024
5025     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
5026
5027     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5028
5029     /* ProcessComponents, per-user */
5030     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5032     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5033     ok(delete_pf("msitest", FALSE), "File not installed\n");
5034
5035     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
5036
5037     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5039
5040     size = MAX_PATH;
5041     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5042                            NULL, NULL, (LPBYTE)val, &size);
5043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5044
5045     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
5046     lstrcatA(program_files_maximus,"\\msitest\\maximus");
5047
5048     ok(!lstrcmpiA(val, program_files_maximus),
5049        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5050
5051     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5052     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5053
5054     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5055     RegDeleteKeyA(comp, "");
5056     RegCloseKey(comp);
5057
5058     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
5059
5060     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5062
5063     size = MAX_PATH;
5064     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5065                            NULL, NULL, (LPBYTE)val, &size);
5066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5067     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5068        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5069
5070     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5071     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5072
5073     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5074     RegDeleteKeyA(comp, "");
5075     RegCloseKey(comp);
5076
5077     /* ProcessComponents, machine */
5078     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
5079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5080     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5081     ok(delete_pf("msitest", FALSE), "File not installed\n");
5082
5083     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
5084
5085     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5087
5088     size = MAX_PATH;
5089     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5090                            NULL, NULL, (LPBYTE)val, &size);
5091     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5092     ok(!lstrcmpiA(val, program_files_maximus),
5093        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5094
5095     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5096     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5097
5098     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5099     RegDeleteKeyA(comp, "");
5100     RegCloseKey(comp);
5101
5102     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
5103
5104     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5106
5107     size = MAX_PATH;
5108     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5109                            NULL, NULL, (LPBYTE)val, &size);
5110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5111     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5112        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5113
5114     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5115     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5116
5117     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5118     RegDeleteKeyA(comp, "");
5119     RegCloseKey(comp);
5120
5121     DeleteFile(msifile);
5122     DeleteFile("msitest\\maximus");
5123     RemoveDirectory("msitest");
5124     LocalFree(usersid);
5125 }
5126
5127 static void test_publish(void)
5128 {
5129     UINT r;
5130     LONG res;
5131     HKEY uninstall, prodkey;
5132     INSTALLSTATE state;
5133     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5134     char date[MAX_PATH];
5135     char temp[MAX_PATH];
5136
5137     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
5138
5139     if (!pMsiQueryComponentStateA)
5140     {
5141         win_skip("MsiQueryComponentStateA is not available\n");
5142         return;
5143     }
5144
5145     get_date_str(date);
5146     GetTempPath(MAX_PATH, temp);
5147
5148     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
5149     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5150
5151     CreateDirectoryA("msitest", NULL);
5152     create_file("msitest\\maximus", 500);
5153
5154     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5155
5156     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5157
5158     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5159     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5160
5161     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5162     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5163
5164     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5165     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5166
5167     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5168                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5169     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5170     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5171
5172     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5173     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5174
5175     /* nothing published */
5176     r = MsiInstallProductA(msifile, NULL);
5177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5178     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5179     ok(pf_exists("msitest"), "File not installed\n");
5180
5181     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5182     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5183
5184     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5185     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5186
5187     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5188     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5189
5190     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5191                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5192     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5193     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5194
5195     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5196     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5197
5198     /* PublishProduct and RegisterProduct */
5199     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
5200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5201     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5202     ok(pf_exists("msitest"), "File not installed\n");
5203
5204     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5205     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5206
5207     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5208     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5209
5210     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5211     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5212
5213     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5214                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5215     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
5216     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5217
5218     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5219     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5220
5221     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5222     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5223     CHECK_REG_STR(prodkey, "InstallDate", date);
5224     CHECK_REG_STR(prodkey, "InstallSource", temp);
5225     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5226     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5227     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5228     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5229     CHECK_REG_STR(prodkey, "Comments", NULL);
5230     CHECK_REG_STR(prodkey, "Contact", NULL);
5231     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5232     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5233     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5234     CHECK_REG_STR(prodkey, "Readme", NULL);
5235     CHECK_REG_STR(prodkey, "Size", NULL);
5236     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5237     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5238     CHECK_REG_DWORD(prodkey, "Language", 1033);
5239     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5240     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5241     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5242     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5243     todo_wine
5244     {
5245         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5246     }
5247
5248     RegCloseKey(prodkey);
5249
5250     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5252     ok(pf_exists("msitest\\maximus"), "File deleted\n");
5253     ok(pf_exists("msitest"), "File deleted\n");
5254
5255     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5256     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5257
5258     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5259     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5260
5261     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5262     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5263
5264     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5265                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5266     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5267     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5268
5269     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5270     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5271
5272     /* complete install */
5273     r = MsiInstallProductA(msifile, "FULL=1");
5274     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5275     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5276     ok(pf_exists("msitest"), "File not installed\n");
5277
5278     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5279     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5280
5281     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5282     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5283
5284     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5285     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5286
5287     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5288                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5290     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5291
5292     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5294
5295     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5296     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5297     CHECK_REG_STR(prodkey, "InstallDate", date);
5298     CHECK_REG_STR(prodkey, "InstallSource", temp);
5299     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5300     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5301     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5302     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5303     CHECK_REG_STR(prodkey, "Comments", NULL);
5304     CHECK_REG_STR(prodkey, "Contact", NULL);
5305     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5306     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5307     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5308     CHECK_REG_STR(prodkey, "Readme", NULL);
5309     CHECK_REG_STR(prodkey, "Size", NULL);
5310     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5311     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5312     CHECK_REG_DWORD(prodkey, "Language", 1033);
5313     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5314     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5315     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5316     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5317     todo_wine
5318     {
5319         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5320     }
5321
5322     RegCloseKey(prodkey);
5323
5324     /* no UnpublishFeatures */
5325     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5326     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5327     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5328     ok(!pf_exists("msitest"), "Directory not deleted\n");
5329
5330     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5331     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5332
5333     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5334     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5335
5336     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5337     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5338
5339     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5340                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5341     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5342     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5343
5344     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5345     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5346
5347     /* complete install */
5348     r = MsiInstallProductA(msifile, "FULL=1");
5349     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5350     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5351     ok(pf_exists("msitest"), "File not installed\n");
5352
5353     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5354     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5355
5356     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5357     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5358
5359     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5360     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5361
5362     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5363                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5364     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5365     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5366
5367     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5369
5370     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5371     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5372     CHECK_REG_STR(prodkey, "InstallDate", date);
5373     CHECK_REG_STR(prodkey, "InstallSource", temp);
5374     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5375     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5376     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5377     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5378     CHECK_REG_STR(prodkey, "Comments", NULL);
5379     CHECK_REG_STR(prodkey, "Contact", NULL);
5380     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5381     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5382     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5383     CHECK_REG_STR(prodkey, "Readme", NULL);
5384     CHECK_REG_STR(prodkey, "Size", NULL);
5385     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5386     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5387     CHECK_REG_DWORD(prodkey, "Language", 1033);
5388     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5389     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5390     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5391     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5392     todo_wine
5393     {
5394         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5395     }
5396
5397     RegCloseKey(prodkey);
5398
5399     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
5400     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
5401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5402     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
5403     todo_wine ok(pf_exists("msitest"), "Directory deleted\n");
5404
5405     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5406     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5407
5408     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5409     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5410
5411     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5412     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5413
5414     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5415                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5417     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5418
5419     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5421
5422     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5423     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5424     CHECK_REG_STR(prodkey, "InstallDate", date);
5425     CHECK_REG_STR(prodkey, "InstallSource", temp);
5426     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5427     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5428     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5429     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5430     CHECK_REG_STR(prodkey, "Comments", NULL);
5431     CHECK_REG_STR(prodkey, "Contact", NULL);
5432     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5433     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5434     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5435     CHECK_REG_STR(prodkey, "Readme", NULL);
5436     CHECK_REG_STR(prodkey, "Size", NULL);
5437     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5438     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5439     CHECK_REG_DWORD(prodkey, "Language", 1033);
5440     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5441     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5442     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5443     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5444     todo_wine
5445     {
5446         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5447     }
5448
5449     RegCloseKey(prodkey);
5450
5451     /* complete install */
5452     r = MsiInstallProductA(msifile, "FULL=1");
5453     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5454     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5455     ok(pf_exists("msitest"), "File not installed\n");
5456
5457     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5458     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5459
5460     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5461     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5462
5463     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5464     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5465
5466     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5467                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5468     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5469     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5470
5471     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5473
5474     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5475     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5476     CHECK_REG_STR(prodkey, "InstallDate", date);
5477     CHECK_REG_STR(prodkey, "InstallSource", temp);
5478     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5479     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5480     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5481     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5482     CHECK_REG_STR(prodkey, "Comments", NULL);
5483     CHECK_REG_STR(prodkey, "Contact", NULL);
5484     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5485     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5486     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5487     CHECK_REG_STR(prodkey, "Readme", NULL);
5488     CHECK_REG_STR(prodkey, "Size", NULL);
5489     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5490     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5491     CHECK_REG_DWORD(prodkey, "Language", 1033);
5492     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5493     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5494     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5495     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5496     todo_wine
5497     {
5498         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
5499     }
5500
5501     RegCloseKey(prodkey);
5502
5503     /* UnpublishFeatures, both features removed */
5504     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
5505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5506     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5507     ok(!pf_exists("msitest"), "Directory not deleted\n");
5508
5509     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5510     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5511
5512     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5513     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5514
5515     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5516     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5517
5518     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5519                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5520     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5521     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5522
5523     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5524     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5525
5526     /* complete install */
5527     r = MsiInstallProductA(msifile, "FULL=1");
5528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5529     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5530     ok(pf_exists("msitest"), "File not installed\n");
5531
5532     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5533     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5534
5535     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5536     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5537
5538     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5539     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5540
5541     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5542                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5543     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5544     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5545
5546     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5548
5549     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5550     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5551     CHECK_REG_STR(prodkey, "InstallDate", date);
5552     CHECK_REG_STR(prodkey, "InstallSource", temp);
5553     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5554     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5555     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5556     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5557     CHECK_REG_STR(prodkey, "Comments", NULL);
5558     CHECK_REG_STR(prodkey, "Contact", NULL);
5559     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5560     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5561     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5562     CHECK_REG_STR(prodkey, "Readme", NULL);
5563     CHECK_REG_STR(prodkey, "Size", NULL);
5564     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5565     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5566     CHECK_REG_DWORD(prodkey, "Language", 1033);
5567     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5568     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5569     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5570     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5571     todo_wine
5572     {
5573         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5574     }
5575
5576     RegCloseKey(prodkey);
5577
5578     /* complete uninstall */
5579     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5580     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5581     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5582     ok(!pf_exists("msitest"), "Directory not deleted\n");
5583
5584     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5585     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5586
5587     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5588     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5589
5590     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5591     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5592
5593     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5594                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5595     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5596     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5597
5598     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5599     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5600
5601     /* make sure 'Program Files\msitest' is removed */
5602     delete_pfmsitest_files();
5603
5604     RegCloseKey(uninstall);
5605     DeleteFile(msifile);
5606     DeleteFile("msitest\\maximus");
5607     RemoveDirectory("msitest");
5608 }
5609
5610 static void test_publishsourcelist(void)
5611 {
5612     UINT r;
5613     DWORD size;
5614     CHAR value[MAX_PATH];
5615     CHAR path[MAX_PATH];
5616     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5617
5618     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
5619     {
5620         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
5621         return;
5622     }
5623
5624     CreateDirectoryA("msitest", NULL);
5625     create_file("msitest\\maximus", 500);
5626
5627     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5628
5629     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5630
5631     r = MsiInstallProductA(msifile, NULL);
5632     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5633     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5634     ok(pf_exists("msitest"), "File not installed\n");
5635
5636     /* nothing published */
5637     size = MAX_PATH;
5638     lstrcpyA(value, "aaa");
5639     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5640                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5641     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5642     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5643     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5644
5645     size = MAX_PATH;
5646     lstrcpyA(value, "aaa");
5647     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5648                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5649     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5650     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5651     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5652
5653     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
5654     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5655     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5656     ok(pf_exists("msitest"), "File not installed\n");
5657
5658     /* after RegisterProduct */
5659     size = MAX_PATH;
5660     lstrcpyA(value, "aaa");
5661     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5662                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5663     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5664     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5665     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5666
5667     size = MAX_PATH;
5668     lstrcpyA(value, "aaa");
5669     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5670                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5671     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5672     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5673     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5674
5675     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5676     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5677     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5678     ok(pf_exists("msitest"), "File not installed\n");
5679
5680     /* after ProcessComponents */
5681     size = MAX_PATH;
5682     lstrcpyA(value, "aaa");
5683     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5684                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5685     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5686     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5687     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5688
5689     size = MAX_PATH;
5690     lstrcpyA(value, "aaa");
5691     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5692                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5693     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5694     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5695     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5696
5697     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
5698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5699     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5700     ok(pf_exists("msitest"), "File not installed\n");
5701
5702     /* after PublishFeatures */
5703     size = MAX_PATH;
5704     lstrcpyA(value, "aaa");
5705     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5706                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5707     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5708     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5709     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5710
5711     size = MAX_PATH;
5712     lstrcpyA(value, "aaa");
5713     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5714                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5715     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5716     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5717     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5718
5719     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
5720     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5721     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5722     ok(pf_exists("msitest"), "File not installed\n");
5723
5724     /* after PublishProduct */
5725     size = MAX_PATH;
5726     lstrcpyA(value, "aaa");
5727     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5728                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5730     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
5731     ok(size == 11, "Expected 11, got %d\n", size);
5732
5733     size = MAX_PATH;
5734     lstrcpyA(value, "aaa");
5735     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5736                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
5737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5738     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5739     ok(size == 0, "Expected 0, got %d\n", size);
5740
5741     size = MAX_PATH;
5742     lstrcpyA(value, "aaa");
5743     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5744                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
5745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5746     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5747     ok(size == 0, "Expected 0, got %d\n", size);
5748
5749     lstrcpyA(path, CURR_DIR);
5750     lstrcatA(path, "\\");
5751
5752     size = MAX_PATH;
5753     lstrcpyA(value, "aaa");
5754     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5755                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
5756     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5757     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5758     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5759
5760     size = MAX_PATH;
5761     lstrcpyA(value, "aaa");
5762     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5763                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
5764     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5765     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
5766     ok(size == 1, "Expected 1, got %d\n", size);
5767
5768     size = MAX_PATH;
5769     lstrcpyA(value, "aaa");
5770     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5771                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5772     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5773     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5774     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5775
5776     size = MAX_PATH;
5777     lstrcpyA(value, "aaa");
5778     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5779                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
5780     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5781     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5782     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5783
5784     size = MAX_PATH;
5785     lstrcpyA(value, "aaa");
5786     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5787                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
5788     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5789     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5790     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5791
5792     /* complete uninstall */
5793     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5795     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5796     ok(!pf_exists("msitest"), "Directory not deleted\n");
5797
5798     /* make sure 'Program Files\msitest' is removed */
5799     delete_pfmsitest_files();
5800
5801     DeleteFile(msifile);
5802     DeleteFile("msitest\\maximus");
5803     RemoveDirectory("msitest");
5804 }
5805
5806 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
5807 {
5808     MSIHANDLE hview = 0;
5809     UINT r;
5810
5811     r = MsiDatabaseOpenView(hdb, query, &hview);
5812     if(r != ERROR_SUCCESS)
5813         return r;
5814
5815     r = MsiViewExecute(hview, hrec);
5816     if(r == ERROR_SUCCESS)
5817         r = MsiViewClose(hview);
5818     MsiCloseHandle(hview);
5819     return r;
5820 }
5821
5822 static void set_transform_summary_info(void)
5823 {
5824     UINT r;
5825     MSIHANDLE suminfo = 0;
5826
5827     /* build summary info */
5828     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
5829     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
5830
5831     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
5832     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5833
5834     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
5835                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5836                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5837                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
5838     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
5839
5840     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
5841     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5842
5843     r = MsiSummaryInfoPersist(suminfo);
5844     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
5845
5846     r = MsiCloseHandle(suminfo);
5847     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
5848 }
5849
5850 static void generate_transform(void)
5851 {
5852     MSIHANDLE hdb1, hdb2;
5853     LPCSTR query;
5854     UINT r;
5855
5856     /* start with two identical databases */
5857     CopyFile(msifile, msifile2, FALSE);
5858
5859     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
5860     ok(r == ERROR_SUCCESS , "Failed to create database\n");
5861
5862     r = MsiDatabaseCommit(hdb1);
5863     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
5864
5865     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
5866     ok(r == ERROR_SUCCESS , "Failed to create database\n");
5867
5868     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
5869     r = run_query(hdb1, 0, query);
5870     ok(r == ERROR_SUCCESS, "failed to add property\n");
5871
5872     /* database needs to be committed */
5873     MsiDatabaseCommit(hdb1);
5874
5875     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
5876     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
5877
5878 #if 0  /* not implemented in wine yet */
5879     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
5880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5881 #endif
5882
5883     MsiCloseHandle(hdb1);
5884     MsiCloseHandle(hdb2);
5885 }
5886
5887 /* data for generating a transform */
5888
5889 /* tables transform names - encoded as they would be in an msi database file */
5890 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
5891 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
5892 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
5893
5894 /* data in each table */
5895 static const char data1[] = /* _StringData */
5896     "propval";  /* all the strings squashed together */
5897
5898 static const WCHAR data2[] = { /* _StringPool */
5899 /*  len, refs */
5900     0,   0,    /* string 0 ''     */
5901     4,   1,    /* string 1 'prop' */
5902     3,   1,    /* string 2 'val'  */
5903 };
5904
5905 static const WCHAR data3[] = { /* Property */
5906     0x0201, 0x0001, 0x0002,
5907 };
5908
5909 static const struct {
5910     LPCWSTR name;
5911     const void *data;
5912     DWORD size;
5913 } table_transform_data[] =
5914 {
5915     { name1, data1, sizeof data1 - 1 },
5916     { name2, data2, sizeof data2 },
5917     { name3, data3, sizeof data3 },
5918 };
5919
5920 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
5921
5922 static void generate_transform_manual(void)
5923 {
5924     IStorage *stg = NULL;
5925     IStream *stm;
5926     WCHAR name[0x20];
5927     HRESULT r;
5928     DWORD i, count;
5929     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
5930
5931     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
5932
5933     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
5934
5935     r = StgCreateDocfile(name, mode, 0, &stg);
5936     ok(r == S_OK, "failed to create storage\n");
5937     if (!stg)
5938         return;
5939
5940     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
5941     ok(r == S_OK, "failed to set storage type\n");
5942
5943     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
5944     {
5945         r = IStorage_CreateStream(stg, table_transform_data[i].name,
5946                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
5947         if (FAILED(r))
5948         {
5949             ok(0, "failed to create stream %08x\n", r);
5950             continue;
5951         }
5952
5953         r = IStream_Write(stm, table_transform_data[i].data,
5954                           table_transform_data[i].size, &count);
5955         if (FAILED(r) || count != table_transform_data[i].size)
5956             ok(0, "failed to write stream\n");
5957         IStream_Release(stm);
5958     }
5959
5960     IStorage_Release(stg);
5961
5962     set_transform_summary_info();
5963 }
5964
5965 static void test_transformprop(void)
5966 {
5967     UINT r;
5968
5969     CreateDirectoryA("msitest", NULL);
5970     create_file("msitest\\augustus", 500);
5971
5972     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
5973
5974     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5975
5976     r = MsiInstallProductA(msifile, NULL);
5977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5978     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5979     ok(!delete_pf("msitest", FALSE), "File installed\n");
5980
5981     if (0)
5982         generate_transform();
5983     else
5984         generate_transform_manual();
5985
5986     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
5987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5988     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5989     ok(delete_pf("msitest", FALSE), "File not installed\n");
5990
5991     /* Delete the files in the temp (current) folder */
5992     DeleteFile(msifile);
5993     DeleteFile(msifile2);
5994     DeleteFile(mstfile);
5995     DeleteFile("msitest\\augustus");
5996     RemoveDirectory("msitest");
5997 }
5998
5999 static void test_currentworkingdir(void)
6000 {
6001     UINT r;
6002     CHAR drive[MAX_PATH], path[MAX_PATH];
6003     LPSTR ptr;
6004
6005     CreateDirectoryA("msitest", NULL);
6006     create_file("msitest\\augustus", 500);
6007
6008     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
6009
6010     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6011
6012     CreateDirectoryA("diffdir", NULL);
6013     SetCurrentDirectoryA("diffdir");
6014
6015     sprintf(path, "..\\%s", msifile);
6016     r = MsiInstallProductA(path, NULL);
6017     todo_wine
6018     {
6019         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
6020         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6021         ok(!delete_pf("msitest", FALSE), "File installed\n");
6022     }
6023
6024     sprintf(path, "%s\\%s", CURR_DIR, msifile);
6025     r = MsiInstallProductA(path, NULL);
6026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6027     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6028     ok(delete_pf("msitest", FALSE), "File not installed\n");
6029
6030     lstrcpyA(drive, CURR_DIR);
6031     drive[2] = '\\';
6032     drive[3] = '\0';
6033     SetCurrentDirectoryA(drive);
6034
6035     lstrcpy(path, CURR_DIR);
6036     if (path[lstrlenA(path) - 1] != '\\')
6037         lstrcatA(path, "\\");
6038     lstrcatA(path, msifile);
6039     ptr = strchr(path, ':');
6040     ptr +=2;
6041
6042     r = MsiInstallProductA(ptr, NULL);
6043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6044     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6045     ok(delete_pf("msitest", FALSE), "File not installed\n");
6046
6047     SetCurrentDirectoryA(CURR_DIR);
6048
6049     DeleteFile(msifile);
6050     DeleteFile("msitest\\augustus");
6051     RemoveDirectory("msitest");
6052     RemoveDirectory("diffdir");
6053 }
6054
6055 static void set_admin_summary_info(const CHAR *name)
6056 {
6057     MSIHANDLE db, summary;
6058     UINT r;
6059
6060     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
6061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6062
6063     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6064     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6065
6066     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
6067     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6068
6069     /* write the summary changes back to the stream */
6070     r = MsiSummaryInfoPersist(summary);
6071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6072
6073     MsiCloseHandle(summary);
6074
6075     r = MsiDatabaseCommit(db);
6076     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6077
6078     MsiCloseHandle(db);
6079 }
6080
6081 static void test_admin(void)
6082 {
6083     UINT r;
6084
6085     CreateDirectoryA("msitest", NULL);
6086     create_file("msitest\\augustus", 500);
6087
6088     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
6089     set_admin_summary_info(msifile);
6090
6091     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6092
6093     r = MsiInstallProductA(msifile, NULL);
6094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6095     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6096     ok(!delete_pf("msitest", FALSE), "File installed\n");
6097     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
6098     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
6099
6100     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
6101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6102     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6103     ok(!delete_pf("msitest", FALSE), "File installed\n");
6104     todo_wine
6105     {
6106         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
6107         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
6108     }
6109
6110     DeleteFile(msifile);
6111     DeleteFile("msitest\\augustus");
6112     RemoveDirectory("msitest");
6113 }
6114
6115 static void set_admin_property_stream(LPCSTR file)
6116 {
6117     IStorage *stg;
6118     IStream *stm;
6119     WCHAR fileW[MAX_PATH];
6120     HRESULT hr;
6121     DWORD count;
6122     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
6123
6124     /* AdminProperties */
6125     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
6126     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
6127         'M','y','P','r','o','p','=','4','2',0};
6128
6129     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
6130
6131     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
6132     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6133     if (!stg)
6134         return;
6135
6136     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
6137     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6138
6139     hr = IStream_Write(stm, data, sizeof(data), &count);
6140     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6141
6142     IStream_Release(stm);
6143     IStorage_Release(stg);
6144 }
6145
6146 static void test_adminprops(void)
6147 {
6148     UINT r;
6149
6150     CreateDirectoryA("msitest", NULL);
6151     create_file("msitest\\augustus", 500);
6152
6153     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
6154     set_admin_summary_info(msifile);
6155     set_admin_property_stream(msifile);
6156
6157     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6158
6159     r = MsiInstallProductA(msifile, NULL);
6160     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6161     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6162     ok(delete_pf("msitest", FALSE), "File installed\n");
6163
6164     DeleteFile(msifile);
6165     DeleteFile("msitest\\augustus");
6166     RemoveDirectory("msitest");
6167 }
6168
6169 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
6170 {
6171     CHAR path[MAX_PATH];
6172
6173     lstrcpyA(path, PROG_FILES_DIR);
6174     lstrcatA(path, "\\");
6175     lstrcatA(path, file);
6176
6177     if (is_file)
6178         create_file_data(path, data, 500);
6179     else
6180         CreateDirectoryA(path, NULL);
6181 }
6182
6183 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
6184
6185 static void test_removefiles(void)
6186 {
6187     UINT r;
6188
6189     CreateDirectoryA("msitest", NULL);
6190     create_file("msitest\\hydrogen", 500);
6191     create_file("msitest\\helium", 500);
6192     create_file("msitest\\lithium", 500);
6193
6194     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
6195
6196     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6197
6198     r = MsiInstallProductA(msifile, NULL);
6199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6200     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6201     ok(!pf_exists("msitest\\helium"), "File installed\n");
6202     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6203     ok(pf_exists("msitest"), "File not installed\n");
6204
6205     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6207     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6208     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
6209     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6210     ok(delete_pf("msitest", FALSE), "File deleted\n");
6211
6212     create_pf("msitest", FALSE);
6213     create_pf("msitest\\hydrogen", TRUE);
6214     create_pf("msitest\\helium", TRUE);
6215     create_pf("msitest\\lithium", TRUE);
6216
6217     r = MsiInstallProductA(msifile, NULL);
6218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6219     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6220     ok(pf_exists("msitest\\helium"), "File not installed\n");
6221     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6222     ok(pf_exists("msitest"), "File not installed\n");
6223
6224     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6225     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6226     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6227     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
6228     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6229     ok(delete_pf("msitest", FALSE), "File deleted\n");
6230
6231     create_pf("msitest", FALSE);
6232     create_pf("msitest\\furlong", TRUE);
6233     create_pf("msitest\\firkin", TRUE);
6234     create_pf("msitest\\fortnight", TRUE);
6235     create_pf("msitest\\becquerel", TRUE);
6236     create_pf("msitest\\dioptre", TRUE);
6237     create_pf("msitest\\attoparsec", TRUE);
6238     create_pf("msitest\\storeys", TRUE);
6239     create_pf("msitest\\block", TRUE);
6240     create_pf("msitest\\siriometer", TRUE);
6241     create_pf("msitest\\cabout", FALSE);
6242     create_pf("msitest\\cabout\\blocker", TRUE);
6243
6244     r = MsiInstallProductA(msifile, NULL);
6245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6246     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6247     ok(!pf_exists("msitest\\helium"), "File installed\n");
6248     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6249     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
6250     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
6251     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
6252     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
6253     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
6254     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
6255     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
6256     ok(!pf_exists("msitest\\block"), "File not deleted\n");
6257     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
6258     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
6259     ok(pf_exists("msitest"), "File not installed\n");
6260
6261     create_pf("msitest\\furlong", TRUE);
6262     create_pf("msitest\\firkin", TRUE);
6263     create_pf("msitest\\fortnight", TRUE);
6264     create_pf("msitest\\storeys", TRUE);
6265     create_pf("msitest\\block", TRUE);
6266     create_pf("msitest\\siriometer", TRUE);
6267
6268     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6269     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6270     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
6271     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
6272     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6273     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
6274     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
6275     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
6276     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
6277     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
6278     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
6279     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
6280     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
6281     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
6282     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6283     ok(pf_exists("msitest"), "Directory deleted\n");
6284
6285     r = MsiInstallProductA(msifile, NULL);
6286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6287     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
6288     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
6289     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
6290     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6291     ok(pf_exists("msitest"), "Directory deleted\n");
6292
6293     delete_pf("msitest\\cabout\\blocker", TRUE);
6294
6295     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6297     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
6298     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
6299
6300     DeleteFile(msifile);
6301     DeleteFile("msitest\\hydrogen");
6302     DeleteFile("msitest\\helium");
6303     DeleteFile("msitest\\lithium");
6304     RemoveDirectory("msitest");
6305 }
6306
6307 static void test_movefiles(void)
6308 {
6309     UINT r;
6310     char props[MAX_PATH];
6311
6312     CreateDirectoryA("msitest", NULL);
6313     create_file("msitest\\augustus", 100);
6314     create_file("cameroon", 100);
6315     create_file("djibouti", 100);
6316     create_file("egypt", 100);
6317     create_file("finland", 100);
6318     create_file("gambai", 100);
6319     create_file("honduras", 100);
6320     create_file("msitest\\india", 100);
6321     create_file("japan", 100);
6322     create_file("kenya", 100);
6323     CreateDirectoryA("latvia", NULL);
6324     create_file("nauru", 100);
6325     create_file("peru", 100);
6326     create_file("apple", 100);
6327     create_file("application", 100);
6328     create_file("ape", 100);
6329     create_file("foo", 100);
6330     create_file("fao", 100);
6331     create_file("fbod", 100);
6332     create_file("budding", 100);
6333     create_file("buddy", 100);
6334     create_file("bud", 100);
6335     create_file("bar", 100);
6336     create_file("bur", 100);
6337     create_file("bird", 100);
6338
6339     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
6340
6341     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6342
6343     /* if the source or dest property is not a full path,
6344      * windows tries to access it as a network resource
6345      */
6346
6347     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
6348             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
6349             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
6350
6351     r = MsiInstallProductA(msifile, props);
6352     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6353     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6354     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
6355     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
6356     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
6357     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
6358     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
6359     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
6360     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
6361     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
6362     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
6363     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
6364     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
6365     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
6366     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
6367     /* either apple or application will be moved depending on directory order */
6368     if (!delete_pf("msitest\\apple", TRUE))
6369         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
6370     else
6371         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
6372     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
6373     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
6374     /* either fao or foo will be moved depending on directory order */
6375     if (delete_pf("msitest\\foo", TRUE))
6376         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
6377     else
6378         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
6379     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
6380     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
6381     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
6382     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
6383     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
6384     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
6385     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
6386     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
6387     ok(delete_pf("msitest", FALSE), "File not installed\n");
6388     ok(DeleteFileA("cameroon"), "File moved\n");
6389     ok(!DeleteFileA("djibouti"), "File not moved\n");
6390     ok(DeleteFileA("egypt"), "File moved\n");
6391     ok(DeleteFileA("finland"), "File moved\n");
6392     ok(DeleteFileA("gambai"), "File moved\n");
6393     ok(!DeleteFileA("honduras"), "File not moved\n");
6394     ok(DeleteFileA("msitest\\india"), "File moved\n");
6395     ok(DeleteFileA("japan"), "File moved\n");
6396     ok(!DeleteFileA("kenya"), "File not moved\n");
6397     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
6398     ok(!DeleteFileA("nauru"), "File not moved\n");
6399     ok(!DeleteFileA("peru"), "File not moved\n");
6400     ok(!DeleteFileA("apple"), "File not moved\n");
6401     ok(!DeleteFileA("application"), "File not moved\n");
6402     ok(DeleteFileA("ape"), "File moved\n");
6403     ok(!DeleteFileA("foo"), "File not moved\n");
6404     ok(!DeleteFileA("fao"), "File not moved\n");
6405     ok(DeleteFileA("fbod"), "File moved\n");
6406     ok(!DeleteFileA("budding"), "File not moved\n");
6407     ok(!DeleteFileA("buddy"), "File not moved\n");
6408     ok(DeleteFileA("bud"), "File moved\n");
6409     ok(!DeleteFileA("bar"), "File not moved\n");
6410     ok(!DeleteFileA("bur"), "File not moved\n");
6411     ok(DeleteFileA("bird"), "File moved\n");
6412
6413     DeleteFile("msitest\\augustus");
6414     RemoveDirectory("msitest");
6415     DeleteFile(msifile);
6416 }
6417
6418 static void test_missingcab(void)
6419 {
6420     UINT r;
6421
6422     CreateDirectoryA("msitest", NULL);
6423     create_file("msitest\\augustus", 500);
6424     create_file("maximus", 500);
6425
6426     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
6427
6428     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6429
6430     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6431
6432     create_pf("msitest", FALSE);
6433     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6434
6435     r = MsiInstallProductA(msifile, NULL);
6436     ok(r == ERROR_SUCCESS ||
6437        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
6438        "Expected ERROR_SUCCESS, got %u\n", r);
6439     if (r == ERROR_SUCCESS)
6440     {
6441       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6442       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6443     }
6444     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
6445     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
6446     ok(delete_pf("msitest", FALSE), "File not installed\n");
6447
6448     create_pf("msitest", FALSE);
6449     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6450     create_pf("msitest\\gaius", TRUE);
6451
6452     r = MsiInstallProductA(msifile, "GAIUS=1");
6453     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6454     todo_wine
6455     {
6456         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
6457         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6458     }
6459     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
6460     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
6461     ok(delete_pf("msitest", FALSE), "File not installed\n");
6462
6463     DeleteFile("msitest\\augustus");
6464     RemoveDirectory("msitest");
6465     DeleteFile("maximus");
6466     DeleteFile("test1.cab");
6467     DeleteFile(msifile);
6468 }
6469
6470 static void test_duplicatefiles(void)
6471 {
6472     UINT r;
6473
6474     CreateDirectoryA("msitest", NULL);
6475     create_file("msitest\\maximus", 500);
6476     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
6477
6478     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6479
6480     /* fails if the destination folder is not a valid property */
6481
6482     r = MsiInstallProductA(msifile, NULL);
6483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6484     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6485     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
6486     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
6487     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
6488     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
6489     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
6490     ok(delete_pf("msitest", FALSE), "File not installed\n");
6491
6492     DeleteFile("msitest\\maximus");
6493     RemoveDirectory("msitest");
6494     DeleteFile(msifile);
6495 }
6496
6497 static void test_writeregistryvalues(void)
6498 {
6499     UINT r;
6500     LONG res;
6501     HKEY hkey;
6502     DWORD type, size;
6503     CHAR path[MAX_PATH];
6504
6505     CreateDirectoryA("msitest", NULL);
6506     create_file("msitest\\augustus", 500);
6507
6508     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
6509
6510     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6511
6512     r = MsiInstallProductA(msifile, NULL);
6513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6514     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6515     ok(delete_pf("msitest", FALSE), "File installed\n");
6516
6517     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
6518     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6519
6520     size = MAX_PATH;
6521     type = REG_MULTI_SZ;
6522     memset(path, 'a', MAX_PATH);
6523     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
6524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6525     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
6526     ok(size == 15, "Expected 15, got %d\n", size);
6527     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
6528
6529     DeleteFile(msifile);
6530     DeleteFile("msitest\\augustus");
6531     RemoveDirectory("msitest");
6532
6533     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
6534     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
6535 }
6536
6537 static void test_sourcefolder(void)
6538 {
6539     UINT r;
6540
6541     CreateDirectoryA("msitest", NULL);
6542     create_file("augustus", 500);
6543
6544     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
6545
6546     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6547
6548     r = MsiInstallProductA(msifile, NULL);
6549     ok(r == ERROR_INSTALL_FAILURE,
6550        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6551     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6552     todo_wine
6553     {
6554         ok(!delete_pf("msitest", FALSE), "File installed\n");
6555     }
6556
6557     RemoveDirectoryA("msitest");
6558
6559     r = MsiInstallProductA(msifile, NULL);
6560     ok(r == ERROR_INSTALL_FAILURE,
6561        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6562     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6563     todo_wine
6564     {
6565         ok(!delete_pf("msitest", FALSE), "File installed\n");
6566     }
6567
6568     DeleteFile(msifile);
6569     DeleteFile("augustus");
6570 }
6571
6572 static void test_customaction51(void)
6573 {
6574     UINT r;
6575
6576     CreateDirectoryA("msitest", NULL);
6577     create_file("msitest\\augustus", 500);
6578
6579     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6580
6581     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6582
6583     r = MsiInstallProductA(msifile, NULL);
6584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6585     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6586     ok(delete_pf("msitest", FALSE), "File installed\n");
6587
6588     DeleteFile(msifile);
6589     DeleteFile("msitest\\augustus");
6590     RemoveDirectory("msitest");
6591 }
6592
6593 static void test_installstate(void)
6594 {
6595     UINT r;
6596
6597     CreateDirectoryA("msitest", NULL);
6598     create_file("msitest\\alpha", 500);
6599     create_file("msitest\\beta", 500);
6600     create_file("msitest\\gamma", 500);
6601     create_file("msitest\\theta", 500);
6602     create_file("msitest\\delta", 500);
6603     create_file("msitest\\epsilon", 500);
6604     create_file("msitest\\zeta", 500);
6605     create_file("msitest\\iota", 500);
6606     create_file("msitest\\eta", 500);
6607     create_file("msitest\\kappa", 500);
6608     create_file("msitest\\lambda", 500);
6609     create_file("msitest\\mu", 500);
6610
6611     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
6612
6613     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6614
6615     r = MsiInstallProductA(msifile, NULL);
6616     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6617     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6618     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6619     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6620     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6621     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6622     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6623     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6624     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6625     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6626     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6627     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6628     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6629     ok(delete_pf("msitest", FALSE), "File not installed\n");
6630
6631     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
6632     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6633     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6634     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6635     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6636     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6637     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6638     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
6639     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6640     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6641     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
6642     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6643     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6644     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6645     ok(delete_pf("msitest", FALSE), "File not installed\n");
6646
6647     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
6648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6649     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6650     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6651     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6652     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6653     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6654     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6655     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6656     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6657     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6658     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6659     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6660     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6661     ok(delete_pf("msitest", FALSE), "File not installed\n");
6662
6663     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
6664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6665     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
6666     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6667     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6668     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
6669     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6670     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6671     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6672     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6673     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6674     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6675     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6676     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6677     ok(!delete_pf("msitest", FALSE), "File installed\n");
6678
6679     DeleteFile(msifile);
6680     DeleteFile("msitest\\alpha");
6681     DeleteFile("msitest\\beta");
6682     DeleteFile("msitest\\gamma");
6683     DeleteFile("msitest\\theta");
6684     DeleteFile("msitest\\delta");
6685     DeleteFile("msitest\\epsilon");
6686     DeleteFile("msitest\\zeta");
6687     DeleteFile("msitest\\iota");
6688     DeleteFile("msitest\\eta");
6689     DeleteFile("msitest\\kappa");
6690     DeleteFile("msitest\\lambda");
6691     DeleteFile("msitest\\mu");
6692     RemoveDirectory("msitest");
6693 }
6694
6695 struct sourcepathmap
6696 {
6697     BOOL sost; /* shortone\shorttwo */
6698     BOOL solt; /* shortone\longtwo */
6699     BOOL lost; /* longone\shorttwo */
6700     BOOL lolt; /* longone\longtwo */
6701     BOOL soste; /* shortone\shorttwo source exists */
6702     BOOL solte; /* shortone\longtwo source exists */
6703     BOOL loste; /* longone\shorttwo source exists */
6704     BOOL lolte; /* longone\longtwo source exists */
6705     UINT err;
6706     DWORD size;
6707 } spmap[256] =
6708 {
6709     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6710     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6711     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6712     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6713     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6714     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6715     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6716     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6717     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6718     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6719     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6720     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6721     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6722     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6723     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6724     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6725     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6726     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6727     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6728     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6729     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6730     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6731     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6732     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6733     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6734     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6735     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6736     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6737     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6738     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6739     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6740     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6741     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6742     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6743     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6744     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6745     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6746     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6747     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6748     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6749     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6750     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6751     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6752     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6753     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6754     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6755     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6756     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6757     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6758     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6759     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6760     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6761     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6762     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6763     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6764     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6765     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6766     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6767     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6768     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6769     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6770     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6771     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6772     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6773     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6774     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6775     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6776     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6777     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6778     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6779     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6780     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6781     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6782     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6783     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6784     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6785     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6786     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6787     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6788     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6789     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6790     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6791     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6792     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6793     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6794     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6795     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6796     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6797     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6798     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6799     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6800     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6801     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6802     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6803     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6804     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6805     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6806     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6807     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6808     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6809     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6810     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6811     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6812     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6813     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6814     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6815     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6816     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6817     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6818     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6819     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6820     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6821     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6822     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6823     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6824     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6825     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6826     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6827     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6828     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6829     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6830     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6831     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6832     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6833     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6834     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6835     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6836     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6837     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6838     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6839     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6840     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6841     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6842     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6843     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6844     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6845     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6846     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6847     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6848     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6849     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6850     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6851     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6852     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6853     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6854     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6855     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6856     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6857     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6858     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6859     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6860     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6861     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6862     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6863     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6864     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6865     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6866     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6867     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6868     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6869     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6870     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6871     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6872     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6873     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6874     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6875     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6876     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6877     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6878     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6879     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6880     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6881     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6882     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6883     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6884     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6885     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6886     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6887     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6888     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6889     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6890     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6891     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6892     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6893     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6894     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6895     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6896     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6897     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6898     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6899     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6900     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6901     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6902     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6903     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6904     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6905     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6906     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6907     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6908     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6909     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6910     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6911     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6912     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6913     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6914     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6915     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6916     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6917     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6918     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6919     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6920     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6921     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6922     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6923     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6924     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6925     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6926     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6927     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6928     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6929     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6930     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6931     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6932     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6933     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6934     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6935     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6936     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6937     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6938     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6939     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6940     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6941     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6942     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6943     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6944     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6945     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6946     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6947     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6948     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6949     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6950     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6951     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6952     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6953     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6954     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6955     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6956     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6957     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6958     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6959     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6960     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6961     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6962     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6963     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6964     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6965 };
6966
6967 static DWORD get_pf_file_size(LPCSTR file)
6968 {
6969     CHAR path[MAX_PATH];
6970     HANDLE hfile;
6971     DWORD size;
6972
6973     lstrcpyA(path, PROG_FILES_DIR);
6974     lstrcatA(path, "\\");
6975     lstrcatA(path, file);
6976
6977     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
6978     if (hfile == INVALID_HANDLE_VALUE)
6979         return 0;
6980
6981     size = GetFileSize(hfile, NULL);
6982     CloseHandle(hfile);
6983     return size;
6984 }
6985
6986 static void test_sourcepath(void)
6987 {
6988     UINT r, i;
6989
6990     if (!winetest_interactive)
6991     {
6992         skip("Run in interactive mode to run source path tests.\n");
6993         return;
6994     }
6995
6996     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
6997
6998     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6999
7000     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
7001     {
7002         if (spmap[i].sost)
7003         {
7004             CreateDirectoryA("shortone", NULL);
7005             CreateDirectoryA("shortone\\shorttwo", NULL);
7006         }
7007
7008         if (spmap[i].solt)
7009         {
7010             CreateDirectoryA("shortone", NULL);
7011             CreateDirectoryA("shortone\\longtwo", NULL);
7012         }
7013
7014         if (spmap[i].lost)
7015         {
7016             CreateDirectoryA("longone", NULL);
7017             CreateDirectoryA("longone\\shorttwo", NULL);
7018         }
7019
7020         if (spmap[i].lolt)
7021         {
7022             CreateDirectoryA("longone", NULL);
7023             CreateDirectoryA("longone\\longtwo", NULL);
7024         }
7025
7026         if (spmap[i].soste)
7027             create_file("shortone\\shorttwo\\augustus", 50);
7028         if (spmap[i].solte)
7029             create_file("shortone\\longtwo\\augustus", 100);
7030         if (spmap[i].loste)
7031             create_file("longone\\shorttwo\\augustus", 150);
7032         if (spmap[i].lolte)
7033             create_file("longone\\longtwo\\augustus", 200);
7034
7035         r = MsiInstallProductA(msifile, NULL);
7036         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
7037         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
7038            "%d: Expected %d, got %d\n", i, spmap[i].size,
7039            get_pf_file_size("msitest\\augustus"));
7040
7041         if (r == ERROR_SUCCESS)
7042         {
7043             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
7044             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
7045         }
7046         else
7047         {
7048             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
7049             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
7050         }
7051
7052         DeleteFileA("shortone\\shorttwo\\augustus");
7053         DeleteFileA("shortone\\longtwo\\augustus");
7054         DeleteFileA("longone\\shorttwo\\augustus");
7055         DeleteFileA("longone\\longtwo\\augustus");
7056         RemoveDirectoryA("shortone\\shorttwo");
7057         RemoveDirectoryA("shortone\\longtwo");
7058         RemoveDirectoryA("longone\\shorttwo");
7059         RemoveDirectoryA("longone\\longtwo");
7060         RemoveDirectoryA("shortone");
7061         RemoveDirectoryA("longone");
7062     }
7063
7064     DeleteFileA(msifile);
7065 }
7066
7067 static void test_MsiConfigureProductEx(void)
7068 {
7069     UINT r;
7070     LONG res;
7071     DWORD type, size;
7072     HKEY props, source;
7073     CHAR keypath[MAX_PATH * 2];
7074     CHAR localpack[MAX_PATH];
7075
7076     if (on_win9x)
7077     {
7078         win_skip("Different registry keys on Win9x and WinMe\n");
7079         return;
7080     }
7081
7082     CreateDirectoryA("msitest", NULL);
7083     create_file("msitest\\hydrogen", 500);
7084     create_file("msitest\\helium", 500);
7085     create_file("msitest\\lithium", 500);
7086
7087     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7088
7089     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7090
7091     /* NULL szProduct */
7092     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
7093                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7094     ok(r == ERROR_INVALID_PARAMETER,
7095        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7096
7097     /* empty szProduct */
7098     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
7099                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7100     ok(r == ERROR_INVALID_PARAMETER,
7101        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7102
7103     /* garbage szProduct */
7104     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
7105                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7106     ok(r == ERROR_INVALID_PARAMETER,
7107        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7108
7109     /* guid without brackets */
7110     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7111                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7112                                "PROPVAR=42");
7113     ok(r == ERROR_INVALID_PARAMETER,
7114        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7115
7116     /* guid with brackets */
7117     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7118                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7119                                "PROPVAR=42");
7120     ok(r == ERROR_UNKNOWN_PRODUCT,
7121        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7122
7123     /* same length as guid, but random */
7124     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
7125                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7126                                "PROPVAR=42");
7127     ok(r == ERROR_UNKNOWN_PRODUCT,
7128        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7129
7130     /* product not installed yet */
7131     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7132                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7133                                "PROPVAR=42");
7134     ok(r == ERROR_UNKNOWN_PRODUCT,
7135        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7136
7137     /* install the product, per-user unmanaged */
7138     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7140     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7141     ok(pf_exists("msitest\\helium"), "File not installed\n");
7142     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7143     ok(pf_exists("msitest"), "File not installed\n");
7144
7145     /* product is installed per-user managed, remove it */
7146     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7147                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7148                                "PROPVAR=42");
7149     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7150     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7151     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7152     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7153     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7154
7155     /* product has been removed */
7156     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7157                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7158                                "PROPVAR=42");
7159     ok(r == ERROR_UNKNOWN_PRODUCT,
7160        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7161
7162     /* install the product, machine */
7163     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7165     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7166     ok(pf_exists("msitest\\helium"), "File not installed\n");
7167     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7168     ok(pf_exists("msitest"), "File not installed\n");
7169
7170     /* product is installed machine, remove it */
7171     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7172                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7173                                "PROPVAR=42");
7174     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7175     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7176     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7177     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7178     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7179
7180     /* product has been removed */
7181     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7182                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7183                                "PROPVAR=42");
7184     ok(r == ERROR_UNKNOWN_PRODUCT,
7185        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7186
7187     /* install the product, machine */
7188     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7189     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7190     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7191     ok(pf_exists("msitest\\helium"), "File not installed\n");
7192     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7193     ok(pf_exists("msitest"), "File not installed\n");
7194
7195     DeleteFileA(msifile);
7196
7197     /* local msifile is removed */
7198     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7199                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7200                                "PROPVAR=42");
7201     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7202     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7203     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7204     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7205     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7206
7207     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7208
7209     /* install the product, machine */
7210     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7211     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7212     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7213     ok(pf_exists("msitest\\helium"), "File not installed\n");
7214     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7215     ok(pf_exists("msitest"), "File not installed\n");
7216
7217     DeleteFileA(msifile);
7218
7219     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7220     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7221     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7222
7223     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7225
7226     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7227                          (const BYTE *)"C:\\idontexist.msi", 18);
7228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7229
7230     /* LocalPackage is used to find the cached msi package */
7231     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7232                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7233                                "PROPVAR=42");
7234     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7235        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7236     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7237     ok(pf_exists("msitest\\helium"), "File not installed\n");
7238     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7239     ok(pf_exists("msitest"), "File not installed\n");
7240
7241     RegCloseKey(props);
7242     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7243
7244     /* LastUsedSource (local msi package) can be used as a last resort */
7245     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7246                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7247                                "PROPVAR=42");
7248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7249     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7250     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7251     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7252     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7253
7254     /* install the product, machine */
7255     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7257     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7258     ok(pf_exists("msitest\\helium"), "File not installed\n");
7259     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7260     ok(pf_exists("msitest"), "File not installed\n");
7261
7262     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7263     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7264     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7265
7266     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7268
7269     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7270                          (const BYTE *)"C:\\idontexist.msi", 18);
7271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7272
7273     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
7274     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
7275
7276     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
7277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7278
7279     type = REG_SZ;
7280     size = MAX_PATH;
7281     res = RegQueryValueExA(source, "PackageName", NULL, &type,
7282                            (LPBYTE)localpack, &size);
7283     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7284
7285     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7286                          (const BYTE *)"idontexist.msi", 15);
7287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7288
7289     /* SourceList is altered */
7290     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7291                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7292                                "PROPVAR=42");
7293     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7294        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7295     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7296     ok(pf_exists("msitest\\helium"), "File not installed\n");
7297     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7298     ok(pf_exists("msitest"), "File not installed\n");
7299
7300     /* restore the SourceList */
7301     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7302                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
7303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7304
7305     /* finally remove the product */
7306     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7307                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7308                                "PROPVAR=42");
7309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7310     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7311     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7312     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7313     ok(!delete_pf("msitest", FALSE), "File not removed\n");
7314
7315     DeleteFileA(msifile);
7316     RegCloseKey(source);
7317     RegCloseKey(props);
7318     DeleteFileA("msitest\\hydrogen");
7319     DeleteFileA("msitest\\helium");
7320     DeleteFileA("msitest\\lithium");
7321     RemoveDirectoryA("msitest");
7322 }
7323
7324 static void test_missingcomponent(void)
7325 {
7326     UINT r;
7327
7328     CreateDirectoryA("msitest", NULL);
7329     create_file("msitest\\hydrogen", 500);
7330     create_file("msitest\\helium", 500);
7331     create_file("msitest\\lithium", 500);
7332     create_file("beryllium", 500);
7333
7334     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
7335
7336     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7337
7338     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7339     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7340     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7341     ok(pf_exists("msitest\\helium"), "File not installed\n");
7342     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7343     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7344     ok(pf_exists("msitest"), "File not installed\n");
7345
7346     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
7347     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7348     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7349     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7350     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7351     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7352     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7353
7354     DeleteFileA(msifile);
7355     DeleteFileA("msitest\\hydrogen");
7356     DeleteFileA("msitest\\helium");
7357     DeleteFileA("msitest\\lithium");
7358     DeleteFileA("beryllium");
7359     RemoveDirectoryA("msitest");
7360 }
7361
7362 static void test_sourcedirprop(void)
7363 {
7364     UINT r;
7365     CHAR props[MAX_PATH];
7366
7367     CreateDirectoryA("msitest", NULL);
7368     create_file("msitest\\augustus", 500);
7369
7370     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
7371
7372     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7373
7374     r = MsiInstallProductA(msifile, NULL);
7375     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7376     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7377     ok(delete_pf("msitest", FALSE), "File installed\n");
7378
7379     DeleteFile("msitest\\augustus");
7380     RemoveDirectory("msitest");
7381
7382     CreateDirectoryA("altsource", NULL);
7383     CreateDirectoryA("altsource\\msitest", NULL);
7384     create_file("altsource\\msitest\\augustus", 500);
7385
7386     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
7387
7388     r = MsiInstallProductA(msifile, props);
7389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7390     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7391     ok(delete_pf("msitest", FALSE), "File installed\n");
7392
7393     DeleteFile(msifile);
7394     DeleteFile("altsource\\msitest\\augustus");
7395     RemoveDirectory("altsource\\msitest");
7396     RemoveDirectory("altsource");
7397 }
7398
7399 static void test_adminimage(void)
7400 {
7401     UINT r;
7402
7403     CreateDirectoryA("msitest", NULL);
7404     CreateDirectoryA("msitest\\first", NULL);
7405     CreateDirectoryA("msitest\\second", NULL);
7406     CreateDirectoryA("msitest\\cabout", NULL);
7407     CreateDirectoryA("msitest\\cabout\\new", NULL);
7408     create_file("msitest\\one.txt", 100);
7409     create_file("msitest\\first\\two.txt", 100);
7410     create_file("msitest\\second\\three.txt", 100);
7411     create_file("msitest\\cabout\\four.txt", 100);
7412     create_file("msitest\\cabout\\new\\five.txt", 100);
7413     create_file("msitest\\filename", 100);
7414     create_file("msitest\\service.exe", 100);
7415
7416     create_database_wordcount(msifile, ai_tables,
7417                               sizeof(ai_tables) / sizeof(msi_table),
7418                               msidbSumInfoSourceTypeAdminImage);
7419
7420     r = MsiInstallProductA(msifile, NULL);
7421     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7422
7423     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7424     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7425     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7426     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7427     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7428     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7429     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7430     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7431     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7432     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7433     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7434     ok(delete_pf("msitest", FALSE), "File not installed\n");
7435
7436     DeleteFileA("msitest.msi");
7437     DeleteFileA("msitest\\cabout\\new\\five.txt");
7438     DeleteFileA("msitest\\cabout\\four.txt");
7439     DeleteFileA("msitest\\second\\three.txt");
7440     DeleteFileA("msitest\\first\\two.txt");
7441     DeleteFileA("msitest\\one.txt");
7442     DeleteFileA("msitest\\service.exe");
7443     DeleteFileA("msitest\\filename");
7444     RemoveDirectoryA("msitest\\cabout\\new");
7445     RemoveDirectoryA("msitest\\cabout");
7446     RemoveDirectoryA("msitest\\second");
7447     RemoveDirectoryA("msitest\\first");
7448     RemoveDirectoryA("msitest");
7449 }
7450
7451 static void test_propcase(void)
7452 {
7453     UINT r;
7454
7455     CreateDirectoryA("msitest", NULL);
7456     create_file("msitest\\augustus", 500);
7457
7458     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
7459
7460     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7461
7462     r = MsiInstallProductA(msifile, "MyProp=42");
7463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7464     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
7465     ok(delete_pf("msitest", FALSE), "File not installed\n");
7466
7467     DeleteFile(msifile);
7468     DeleteFile("msitest\\augustus");
7469     RemoveDirectory("msitest");
7470 }
7471
7472 static void test_int_widths( void )
7473 {
7474     static const char int0[] = "int0\ni0\nint0\tint0\n1";
7475     static const char int1[] = "int1\ni1\nint1\tint1\n1";
7476     static const char int2[] = "int2\ni2\nint2\tint2\n1";
7477     static const char int3[] = "int3\ni3\nint3\tint3\n1";
7478     static const char int4[] = "int4\ni4\nint4\tint4\n1";
7479     static const char int5[] = "int5\ni5\nint5\tint5\n1";
7480     static const char int8[] = "int8\ni8\nint8\tint8\n1";
7481
7482     static const struct
7483     {
7484         const char  *data;
7485         unsigned int size;
7486         UINT         ret;
7487     }
7488     tests[] =
7489     {
7490         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
7491         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
7492         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
7493         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
7494         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
7495         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
7496         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
7497     };
7498
7499     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
7500     MSIHANDLE db;
7501     UINT r, i;
7502
7503     GetTempPathA(MAX_PATH, tmpdir);
7504     CreateDirectoryA(tmpdir, NULL);
7505
7506     strcpy(msitable, tmpdir);
7507     strcat(msitable, "\\msitable.idt");
7508
7509     strcpy(msidb, tmpdir);
7510     strcat(msidb, "\\msitest.msi");
7511
7512     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
7513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7514
7515     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
7516     {
7517         write_file(msitable, tests[i].data, tests[i].size);
7518
7519         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
7520         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
7521
7522         r = MsiDatabaseCommit(db);
7523         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7524         DeleteFileA(msitable);
7525     }
7526
7527     MsiCloseHandle(db);
7528     DeleteFileA(msidb);
7529     RemoveDirectoryA(tmpdir);
7530 }
7531
7532 static void test_shortcut(void)
7533 {
7534     UINT r;
7535     HRESULT hr;
7536
7537     create_test_files();
7538     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
7539
7540     r = MsiInstallProductA(msifile, NULL);
7541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7542
7543     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
7544     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7545
7546     r = MsiInstallProductA(msifile, NULL);
7547     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7548
7549     CoUninitialize();
7550
7551     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7552     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7553
7554     r = MsiInstallProductA(msifile, NULL);
7555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7556
7557     CoUninitialize();
7558
7559     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7560     delete_pf("msitest\\cabout\\new", FALSE);
7561     delete_pf("msitest\\cabout\\four.txt", TRUE);
7562     delete_pf("msitest\\cabout", FALSE);
7563     delete_pf("msitest\\changed\\three.txt", TRUE);
7564     delete_pf("msitest\\changed", FALSE);
7565     delete_pf("msitest\\first\\two.txt", TRUE);
7566     delete_pf("msitest\\first", FALSE);
7567     delete_pf("msitest\\filename", TRUE);
7568     delete_pf("msitest\\one.txt", TRUE);
7569     delete_pf("msitest\\service.exe", TRUE);
7570     delete_pf("msitest\\Shortcut.lnk", TRUE);
7571     delete_pf("msitest", FALSE);
7572     delete_test_files();
7573 }
7574
7575 static void test_envvar(void)
7576 {
7577     UINT r;
7578     HKEY env;
7579     LONG res;
7580     DWORD type, size;
7581     char buffer[16];
7582     UINT i;
7583
7584     if (on_win9x)
7585     {
7586         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
7587         return;
7588     }
7589
7590     create_test_files();
7591     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
7592
7593     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
7594     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7595
7596     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
7597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7598
7599     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
7600     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7601
7602     r = MsiInstallProductA(msifile, NULL);
7603     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7604
7605     type = REG_NONE;
7606     size = sizeof(buffer);
7607     buffer[0] = 0;
7608     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
7609     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7610     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7611     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7612
7613     res = RegDeleteValueA(env, "MSITESTVAR1");
7614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7615
7616     type = REG_NONE;
7617     size = sizeof(buffer);
7618     buffer[0] = 0;
7619     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
7620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7621     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7622     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7623
7624     res = RegDeleteValueA(env, "MSITESTVAR2");
7625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7626
7627     res = RegDeleteValueA(env, "MSITESTVAR3");
7628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7629
7630     res = RegDeleteValueA(env, "MSITESTVAR4");
7631     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7632
7633     res = RegDeleteValueA(env, "MSITESTVAR5");
7634     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7635
7636     res = RegDeleteValueA(env, "MSITESTVAR6");
7637     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7638
7639     res = RegDeleteValueA(env, "MSITESTVAR7");
7640     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7641
7642     res = RegDeleteValueA(env, "MSITESTVAR8");
7643     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7644
7645     res = RegDeleteValueA(env, "MSITESTVAR9");
7646     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7647
7648     res = RegDeleteValueA(env, "MSITESTVAR10");
7649     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7650
7651     i = 11;
7652     while (environment_dat_results[(i-11)]) {
7653         char name[20];
7654         sprintf(name, "MSITESTVAR%d", i);
7655
7656         type = REG_NONE;
7657         size = sizeof(buffer);
7658         buffer[0] = 0;
7659         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
7660         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7661         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
7662         ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n",
7663            i, environment_dat_results[(i-11)], buffer);
7664
7665         res = RegDeleteValueA(env, name);
7666         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7667         i++;
7668     }
7669
7670
7671     RegCloseKey(env);
7672     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7673     delete_pf("msitest\\cabout\\new", FALSE);
7674     delete_pf("msitest\\cabout\\four.txt", TRUE);
7675     delete_pf("msitest\\cabout", FALSE);
7676     delete_pf("msitest\\changed\\three.txt", TRUE);
7677     delete_pf("msitest\\changed", FALSE);
7678     delete_pf("msitest\\first\\two.txt", TRUE);
7679     delete_pf("msitest\\first", FALSE);
7680     delete_pf("msitest\\filename", TRUE);
7681     delete_pf("msitest\\one.txt", TRUE);
7682     delete_pf("msitest\\service.exe", TRUE);
7683     delete_pf("msitest", FALSE);
7684     delete_test_files();
7685 }
7686
7687 static void test_preselected(void)
7688 {
7689     UINT r;
7690
7691     create_test_files();
7692     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
7693
7694     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
7695     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7696
7697     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
7698     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
7699     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
7700     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
7701     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
7702     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
7703     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
7704     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
7705     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
7706     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7707     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
7708     ok(delete_pf("msitest", FALSE), "File not installed\n");
7709
7710     r = MsiInstallProductA(msifile, NULL);
7711     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7712
7713     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7714     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7715     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7716     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7717     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7718     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7719     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7720     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7721     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7722     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7723     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7724     ok(delete_pf("msitest", FALSE), "File not installed\n");
7725     delete_test_files();
7726 }
7727
7728 static void test_installed_prop(void)
7729 {
7730     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
7731     UINT r;
7732
7733     create_test_files();
7734     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
7735
7736     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7737
7738     r = MsiInstallProductA(msifile, "FULL=1");
7739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7740
7741     r = MsiInstallProductA(msifile, "FULL=1");
7742     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7743
7744     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
7745     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7746
7747     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7748     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7749     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7750     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7751     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7752     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7753     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7754     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7755     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7756     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7757     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7758     ok(delete_pf("msitest", FALSE), "File not installed\n");
7759
7760     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7762
7763     delete_test_files();
7764 }
7765
7766 static void test_allusers_prop(void)
7767 {
7768     UINT r;
7769
7770     create_test_files();
7771     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
7772
7773     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7774
7775     /* ALLUSERS property unset */
7776     r = MsiInstallProductA(msifile, "FULL=1");
7777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7778
7779     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7780     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7781     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7782     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7783     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7784     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7785     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7786     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7787     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7788     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7789     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7790     ok(delete_pf("msitest", FALSE), "File not installed\n");
7791
7792     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7794
7795     delete_test_files();
7796
7797     create_test_files();
7798     create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
7799
7800     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7801
7802     /* ALLUSERS property set to 1 */
7803     r = MsiInstallProductA(msifile, "FULL=1");
7804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7805
7806     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7807     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7808     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7809     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7810     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7811     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7812     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7813     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7814     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7815     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7816     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7817     ok(delete_pf("msitest", FALSE), "File not installed\n");
7818
7819     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7821
7822     delete_test_files();
7823
7824     create_test_files();
7825     create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
7826
7827     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7828
7829     /* ALLUSERS property set to 2 */
7830     r = MsiInstallProductA(msifile, "FULL=1");
7831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7832
7833     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7834     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7835     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7836     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7837     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7838     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7839     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7840     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7841     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7842     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7843     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7844     ok(delete_pf("msitest", FALSE), "File not installed\n");
7845
7846     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7847     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7848
7849     delete_test_files();
7850
7851     create_test_files();
7852     create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
7853
7854     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7855
7856     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
7857     r = MsiInstallProductA(msifile, "FULL=1");
7858     if (r == ERROR_SUCCESS)
7859     {
7860         /* Win9x/WinMe */
7861         win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n");
7862
7863         ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7864         ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7865         ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7866         ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7867         ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7868         ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7869         ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7870         ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7871         ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7872         ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7873         ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7874         ok(delete_pf("msitest", FALSE), "File not installed\n");
7875
7876         r = MsiInstallProductA(msifile, "REMOVE=ALL");
7877         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7878
7879         delete_test_files();
7880     }
7881     else
7882         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7883 }
7884
7885 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
7886 static char rename_ops[]      = "PendingFileRenameOperations";
7887
7888 static void process_pending_renames(HKEY hkey)
7889 {
7890     char *buf, *src, *dst, *buf2, *buf2ptr;
7891     DWORD size, buf2len = 0;
7892     LONG ret;
7893     BOOL found = FALSE;
7894
7895     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
7896     buf = HeapAlloc(GetProcessHeap(), 0, size);
7897     buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7898     buf[0] = 0;
7899
7900     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
7901     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
7902
7903     for (src = buf; *src; src = dst + strlen(dst) + 1)
7904     {
7905         DWORD flags = MOVEFILE_COPY_ALLOWED;
7906
7907         dst = src + strlen(src) + 1;
7908
7909         if (!strstr(src, "msitest"))
7910         {
7911             lstrcpyA(buf2ptr, src);
7912             buf2len += strlen(src) + 1;
7913             buf2ptr += strlen(src) + 1;
7914             if (*dst)
7915             {
7916                 lstrcpyA(buf2ptr, dst);
7917                 buf2ptr += strlen(dst) + 1;
7918                 buf2len += strlen(dst) + 1;
7919             }
7920             buf2ptr++;
7921             buf2len++;
7922             continue;
7923         }
7924
7925         found = TRUE;
7926
7927         if (*dst == '!')
7928         {
7929             flags |= MOVEFILE_REPLACE_EXISTING;
7930             dst++;
7931         }
7932         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
7933         if (*dst)
7934         {
7935             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
7936             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
7937         }
7938         else
7939             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
7940     }
7941
7942     ok(found, "Expected a 'msitest' entry\n");
7943
7944     if (*buf2)
7945     {
7946         buf2len++;
7947         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len);
7948     }
7949     else
7950         RegDeleteValueA(hkey, rename_ops);
7951
7952     HeapFree(GetProcessHeap(), 0, buf);
7953     HeapFree(GetProcessHeap(), 0, buf2);
7954 }
7955
7956 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
7957 {
7958     DWORD len, data_len = strlen(data);
7959     HANDLE handle;
7960     char buf[128];
7961
7962     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7963     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
7964
7965     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
7966     {
7967         CloseHandle(handle);
7968         return !memcmp(buf, data, data_len);
7969     }
7970     CloseHandle(handle);
7971     return FALSE;
7972 }
7973
7974 static void test_file_in_use(void)
7975 {
7976     UINT r;
7977     HANDLE file;
7978     HKEY hkey;
7979     char path[MAX_PATH];
7980
7981     if (on_win9x)
7982     {
7983         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
7984         return;
7985     }
7986
7987     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
7988
7989     CreateDirectoryA("msitest", NULL);
7990     create_file("msitest\\maximus", 500);
7991     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
7992
7993     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7994
7995     lstrcpy(path, PROG_FILES_DIR);
7996     lstrcat(path, "\\msitest");
7997     CreateDirectoryA(path, NULL);
7998
7999     lstrcat(path, "\\maximus");
8000     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8001
8002     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8003     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8004     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8005     CloseHandle(file);
8006     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8007
8008     process_pending_renames(hkey);
8009     RegCloseKey(hkey);
8010
8011     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
8012     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8013     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8014
8015     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8017
8018     DeleteFileA("msitest\\maximus");
8019     delete_test_files();
8020 }
8021
8022 static void test_file_in_use_cab(void)
8023 {
8024     UINT r;
8025     HANDLE file;
8026     HKEY hkey;
8027     char path[MAX_PATH];
8028
8029     if (on_win9x)
8030     {
8031         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
8032         return;
8033     }
8034
8035     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
8036
8037     CreateDirectoryA("msitest", NULL);
8038     create_file("maximus", 500);
8039     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
8040     DeleteFile("maximus");
8041
8042     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
8043
8044     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8045
8046     lstrcpy(path, PROG_FILES_DIR);
8047     lstrcat(path, "\\msitest");
8048     CreateDirectoryA(path, NULL);
8049
8050     lstrcat(path, "\\maximus");
8051     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8052
8053     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8054     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8055     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8056     CloseHandle(file);
8057     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8058
8059     process_pending_renames(hkey);
8060     RegCloseKey(hkey);
8061
8062     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
8063     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8064     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8065
8066     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8067     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8068
8069     delete_cab_files();
8070     delete_test_files();
8071 }
8072
8073 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
8074 {
8075     return IDOK;
8076 }
8077
8078 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
8079 {
8080     return IDOK;
8081 }
8082
8083 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
8084 {
8085     return IDOK;
8086 }
8087
8088 static void test_MsiSetExternalUI(void)
8089 {
8090     INSTALLUI_HANDLERA ret_a;
8091     INSTALLUI_HANDLERW ret_w;
8092     INSTALLUI_HANDLER_RECORD prev;
8093     UINT error;
8094
8095     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8096     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8097
8098     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8099     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
8100
8101     /* Not present before Installer 3.1 */
8102     if (!pMsiSetExternalUIRecord) {
8103         win_skip("MsiSetExternalUIRecord is not available\n");
8104         return;
8105     }
8106
8107     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8108     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8109     ok(prev == NULL, "expected NULL, got %p\n", prev);
8110
8111     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8112     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
8113     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8114     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8115
8116     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8117     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8118
8119     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8120     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
8121
8122     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8123     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8124
8125     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8126     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8127
8128     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8129     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8130     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8131     ok(prev == NULL, "expected NULL, got %p\n", prev);
8132
8133     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8134     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8135
8136     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8137     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8138
8139     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8140     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
8141     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8142     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8143
8144     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
8145     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8146
8147     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
8148     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8149 }
8150
8151 static void test_feature_override(void)
8152 {
8153     UINT r;
8154
8155     create_test_files();
8156     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
8157
8158     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
8159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8160
8161     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8162     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
8163     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8164     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
8165     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8166     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
8167     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8168     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
8169     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8170     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8171     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8172     ok(delete_pf("msitest", FALSE), "File not installed\n");
8173
8174     delete_test_files();
8175
8176     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest");
8177 }
8178
8179 static void test_create_folder(void)
8180 {
8181     UINT r;
8182
8183     create_test_files();
8184     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
8185
8186     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8187
8188     r = MsiInstallProductA(msifile, NULL);
8189     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8190
8191     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8192     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8193     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8194     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8195     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8196     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8197     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8198     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8199     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8200     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8201     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8202     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8203
8204     r = MsiInstallProductA(msifile, "LOCAL=Two");
8205     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8206
8207     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8208     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8209     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8210     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8211     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8212     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8213     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8214     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8215     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8216     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8217     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8218     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8219
8220     delete_test_files();
8221 }
8222
8223 static void test_remove_folder(void)
8224 {
8225     UINT r;
8226
8227     create_test_files();
8228     create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table));
8229
8230     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8231
8232     r = MsiInstallProductA(msifile, NULL);
8233     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8234
8235     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8236     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8237     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8238     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8239     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8240     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8241     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8242     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8243     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8244     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8245     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8246     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8247
8248     r = MsiInstallProductA(msifile, "LOCAL=Two");
8249     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8250
8251     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8252     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8253     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8254     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8255     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8256     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8257     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8258     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8259     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8260     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8261     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8262     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8263
8264     delete_test_files();
8265 }
8266
8267 static void test_start_services(void)
8268 {
8269     UINT r;
8270     SC_HANDLE scm, service;
8271     BOOL ret;
8272     DWORD error = ERROR_SUCCESS;
8273
8274     if (on_win9x)
8275     {
8276         win_skip("Services are not implemented on Win9x and WinMe\n");
8277         return;
8278     }
8279     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8280     ok(scm != NULL, "Failed to open the SC Manager\n");
8281     if (!scm) return;
8282
8283     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8284     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
8285     {
8286         win_skip("The 'Spooler' service does not exist\n");
8287         CloseServiceHandle(scm);
8288         return;
8289     }
8290     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
8291     if (!service) {
8292         CloseServiceHandle(scm);
8293         return;
8294     }
8295
8296     ret = StartService(service, 0, NULL);
8297     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
8298     {
8299         skip("Terminal service not available, skipping test\n");
8300         CloseServiceHandle(service);
8301         CloseServiceHandle(scm);
8302         return;
8303     }
8304
8305     CloseServiceHandle(service);
8306     CloseServiceHandle(scm);
8307
8308     create_test_files();
8309     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
8310
8311     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8312
8313     r = MsiInstallProductA(msifile, NULL);
8314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8315
8316     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8317     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8318     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8319     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8320     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8321     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8322     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8323     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8324     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8325     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8326     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8327     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8328
8329     delete_test_files();
8330
8331     if (error == ERROR_SUCCESS)
8332     {
8333         SERVICE_STATUS status;
8334
8335         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8336         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8337
8338         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
8339         ok(ret, "ControlService failed %u\n", GetLastError());
8340
8341         CloseServiceHandle(service);
8342         CloseServiceHandle(scm);
8343     }
8344 }
8345
8346 static void test_delete_services(void)
8347 {
8348     UINT r;
8349
8350     create_test_files();
8351     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
8352
8353     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8354
8355     r = MsiInstallProductA(msifile, NULL);
8356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8357
8358     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8359     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8360     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8361     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8362     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8363     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8364     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8365     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8366     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8367     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8368     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8369     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8370
8371     delete_test_files();
8372 }
8373
8374 static void test_self_registration(void)
8375 {
8376     UINT r;
8377
8378     create_test_files();
8379     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
8380
8381     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8382
8383     r = MsiInstallProductA(msifile, NULL);
8384     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8385
8386     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8387     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8388     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8389     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8390     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8391     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8392     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8393     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8394     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8395     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8396     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8397     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8398
8399     delete_test_files();
8400 }
8401
8402 static void test_register_font(void)
8403 {
8404     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
8405     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
8406     LONG ret;
8407     HKEY key;
8408     UINT r;
8409
8410     create_test_files();
8411     create_file("msitest\\font.ttf", 1000);
8412     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
8413
8414     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8415
8416     r = MsiInstallProductA(msifile, NULL);
8417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8418
8419     ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key);
8420     if (ret)
8421         RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key);
8422
8423     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8424     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8425
8426     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8428
8429     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8430
8431     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8432     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8433
8434     RegDeleteValueA(key, "msi test font");
8435     RegCloseKey(key);
8436     DeleteFileA("msitest\\font.ttf");
8437     delete_test_files();
8438 }
8439
8440 static void test_validate_product_id(void)
8441 {
8442     UINT r;
8443
8444     create_test_files();
8445     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
8446
8447     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8448
8449     r = MsiInstallProductA(msifile, NULL);
8450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8451
8452     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
8453     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8454
8455     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
8456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8457
8458     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
8459     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8460
8461     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8462     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8463     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8464     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8465     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8466     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8467     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8468     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8469     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8470     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8471     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8472     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8473
8474     delete_test_files();
8475 }
8476
8477 static void test_install_remove_odbc(void)
8478 {
8479     UINT r;
8480
8481     create_test_files();
8482     create_file("msitest\\ODBCdriver.dll", 1000);
8483     create_file("msitest\\ODBCdriver2.dll", 1000);
8484     create_file("msitest\\ODBCtranslator.dll", 1000);
8485     create_file("msitest\\ODBCtranslator2.dll", 1000);
8486     create_file("msitest\\ODBCsetup.dll", 1000);
8487     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
8488
8489     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8490
8491     r = MsiInstallProductA(msifile, NULL);
8492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8493
8494     ok(delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not created\n");
8495     ok(delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not created\n");
8496     ok(delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not created\n");
8497     ok(delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not created\n");
8498     ok(delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not created\n");
8499     ok(delete_pf("msitest", FALSE), "directory not created\n");
8500
8501     DeleteFileA("msitest\\ODBCdriver.dll");
8502     DeleteFileA("msitest\\ODBCdriver2.dll");
8503     DeleteFileA("msitest\\ODBCtranslator.dll");
8504     DeleteFileA("msitest\\ODBCtranslator2.dll");
8505     DeleteFileA("msitest\\ODBCsetup.dll");
8506     delete_test_files();
8507 }
8508
8509 static void test_register_typelib(void)
8510 {
8511     UINT r;
8512
8513     create_test_files();
8514     create_file("msitest\\typelib.dll", 1000);
8515     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
8516
8517     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8518
8519     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
8520     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8521
8522     r = MsiInstallProductA(msifile, NULL);
8523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8524
8525     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8526     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8527
8528     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
8529     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8530
8531     DeleteFileA("msitest\\typelib.dll");
8532     delete_test_files();
8533 }
8534
8535 static void test_create_remove_shortcut(void)
8536 {
8537     UINT r;
8538
8539     create_test_files();
8540     create_file("msitest\\target.txt", 1000);
8541     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
8542
8543     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8544
8545     r = MsiInstallProductA(msifile, NULL);
8546     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8547
8548     ok(pf_exists("msitest\\target.txt"), "file not created\n");
8549     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
8550
8551     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8553
8554     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
8555     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
8556     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8557
8558     DeleteFileA("msitest\\target.txt");
8559     delete_test_files();
8560 }
8561
8562 static void test_publish_components(void)
8563 {
8564     static char keypath[] =
8565         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
8566
8567     UINT r;
8568     LONG res;
8569     HKEY key;
8570
8571     create_test_files();
8572     create_file("msitest\\english.txt", 1000);
8573     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
8574
8575     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8576
8577     r = MsiInstallProductA(msifile, NULL);
8578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8579
8580     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8581     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
8582
8583     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
8584     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
8585     RegCloseKey(key);
8586
8587     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8588     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8589
8590     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8591     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
8592
8593     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
8594     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8595
8596     DeleteFileA("msitest\\english.txt");
8597     delete_test_files();
8598 }
8599
8600 static void test_remove_duplicate_files(void)
8601 {
8602     UINT r;
8603
8604     create_test_files();
8605     create_file("msitest\\original.txt", 1000);
8606     create_file("msitest\\original2.txt", 1000);
8607     create_file("msitest\\original3.txt", 1000);
8608     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
8609
8610     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8611
8612     r = MsiInstallProductA(msifile, NULL);
8613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8614
8615     ok(pf_exists("msitest\\original.txt"), "file not created\n");
8616     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
8617     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
8618     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
8619     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
8620
8621     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8622     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8623
8624     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
8625     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
8626     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
8627     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
8628     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
8629     ok(delete_pf("msitest", FALSE), "directory removed\n");
8630
8631     DeleteFileA("msitest\\original.txt");
8632     DeleteFileA("msitest\\original2.txt");
8633     DeleteFileA("msitest\\original3.txt");
8634     delete_test_files();
8635 }
8636
8637 static void test_remove_registry_values(void)
8638 {
8639     UINT r;
8640     LONG res;
8641     HKEY key;
8642
8643     create_test_files();
8644     create_file("msitest\\registry.txt", 1000);
8645     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
8646
8647     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8648
8649     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8650     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
8651     RegCloseKey(key);
8652
8653     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8654     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
8655     RegCloseKey(key);
8656
8657     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8658     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8659     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
8660     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8661     RegCloseKey(key);
8662
8663     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8664     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8665     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8666     RegCloseKey(key);
8667
8668     r = MsiInstallProductA(msifile, NULL);
8669     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8670
8671     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8672     ok(res == ERROR_SUCCESS, "key removed\n");
8673     RegCloseKey(key);
8674
8675     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8676     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8677
8678     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8680     RegCloseKey(key);
8681
8682     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8684
8685     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8686     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8687
8688     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8689     ok(res == ERROR_SUCCESS, "key removed\n");
8690     RegCloseKey(key);
8691
8692     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8693     ok(res == ERROR_SUCCESS, "key removed\n");
8694     RegCloseKey(key);
8695
8696     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8697     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8698
8699     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA");
8700     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2");
8701     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine");
8702
8703     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
8704     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8705
8706     DeleteFileA("msitest\\registry.txt");
8707     delete_test_files();
8708 }
8709
8710 static void test_find_related_products(void)
8711 {
8712     UINT r;
8713
8714     create_test_files();
8715     create_file("msitest\\product.txt", 1000);
8716     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
8717
8718     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8719
8720     r = MsiInstallProductA(msifile, NULL);
8721     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8722
8723     /* install again, so it finds the upgrade code */
8724     r = MsiInstallProductA(msifile, NULL);
8725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8726
8727     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8728     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8729
8730     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
8731     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8732
8733     DeleteFileA("msitest\\product.txt");
8734     delete_test_files();
8735 }
8736
8737 static void test_remove_ini_values(void)
8738 {
8739     UINT r;
8740     DWORD len;
8741     char inifile[MAX_PATH], buf[0x10];
8742     HANDLE file;
8743     BOOL ret;
8744
8745     create_test_files();
8746     create_file("msitest\\inifile.txt", 1000);
8747     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
8748
8749     lstrcpyA(inifile, PROG_FILES_DIR);
8750     lstrcatA(inifile, "\\msitest");
8751     CreateDirectoryA(inifile, NULL);
8752     lstrcatA(inifile, "\\test.ini");
8753     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
8754     CloseHandle(file);
8755
8756     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
8757     ok(ret, "failed to write profile string %u\n", GetLastError());
8758
8759     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
8760     ok(ret, "failed to write profile string %u\n", GetLastError());
8761
8762     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8763
8764     r = MsiInstallProductA(msifile, NULL);
8765     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8766
8767     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
8768     ok(len == 6, "got %u expected 6\n", len);
8769
8770     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
8771     ok(!len, "got %u expected 0\n", len);
8772
8773     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8775
8776     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
8777     ok(!len, "got %u expected 0\n", len);
8778
8779     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
8780     ok(!len, "got %u expected 0\n", len);
8781
8782     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
8783     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
8784     ok(delete_pf("msitest", FALSE), "directory removed\n");
8785
8786     DeleteFileA("msitest\\inifile.txt");
8787     delete_test_files();
8788 }
8789
8790 static void test_remove_env_strings(void)
8791 {
8792     UINT r;
8793     LONG res;
8794     HKEY key;
8795     DWORD type, size;
8796     char buffer[0x10];
8797
8798     if (on_win9x)
8799     {
8800         win_skip("Environment variables are handled differently on win9x and winme\n");
8801         return;
8802     }
8803
8804     create_test_files();
8805     create_file("msitest\\envvar.txt", 1000);
8806     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
8807
8808     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8809
8810     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
8811     ok(!res, "failed to open environment key %d\n", res);
8812
8813     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
8814     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
8815     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
8816     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
8817     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
8818
8819     RegCloseKey(key);
8820
8821     r = MsiInstallProductA(msifile, NULL);
8822     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8823
8824     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
8825     ok(!res, "failed to open environment key %d\n", res);
8826
8827     type = REG_NONE;
8828     buffer[0] = 0;
8829     size = sizeof(buffer);
8830     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
8831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8832     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8833     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8834
8835     type = REG_NONE;
8836     buffer[0] = 0;
8837     size = sizeof(buffer);
8838     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
8839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8840     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8841     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8842
8843     type = REG_NONE;
8844     buffer[0] = 0;
8845     size = sizeof(buffer);
8846     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
8847     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8848     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8849     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8850
8851     type = REG_NONE;
8852     buffer[0] = 0;
8853     size = sizeof(buffer);
8854     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
8855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8856     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8857     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8858
8859     type = REG_NONE;
8860     buffer[0] = 0;
8861     size = sizeof(buffer);
8862     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
8863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8864     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8865     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8866
8867     RegCloseKey(key);
8868
8869     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8871
8872     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
8873     ok(!res, "failed to open environment key %d\n", res);
8874
8875     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
8876     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8877
8878     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
8879     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8880
8881     type = REG_NONE;
8882     buffer[0] = 0;
8883     size = sizeof(buffer);
8884     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
8885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8886     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8887     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8888     RegDeleteValueA(key, "MSITESTVAR3");
8889
8890     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
8891     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8892
8893     type = REG_NONE;
8894     buffer[0] = 0;
8895     size = sizeof(buffer);
8896     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
8897     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8898     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8899     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8900     RegDeleteValueA(key, "MSITESTVAR5");
8901
8902     RegCloseKey(key);
8903
8904     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
8905     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8906
8907     DeleteFileA("msitest\\envvar.txt");
8908     delete_test_files();
8909 }
8910
8911 START_TEST(install)
8912 {
8913     DWORD len;
8914     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
8915     STATEMGRSTATUS status;
8916     BOOL ret = FALSE;
8917
8918     init_functionpointers();
8919
8920     on_win9x = check_win9x();
8921
8922     GetCurrentDirectoryA(MAX_PATH, prev_path);
8923     GetTempPath(MAX_PATH, temp_path);
8924     SetCurrentDirectoryA(temp_path);
8925
8926     lstrcpyA(CURR_DIR, temp_path);
8927     len = lstrlenA(CURR_DIR);
8928
8929     if(len && (CURR_DIR[len - 1] == '\\'))
8930         CURR_DIR[len - 1] = 0;
8931
8932     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
8933
8934     /* Create a restore point ourselves so we circumvent the multitude of restore points
8935      * that would have been created by all the installation and removal tests.
8936      */
8937     if (pSRSetRestorePointA)
8938     {
8939         memset(&status, 0, sizeof(status));
8940         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
8941     }
8942
8943     /* Create only one log file and don't append. We have to pass something
8944      * for the log mode for this to work. The logfile needs to have an absolute
8945      * path otherwise we still end up with some extra logfiles as some tests
8946      * change the current directory.
8947      */
8948     lstrcpyA(log_file, temp_path);
8949     lstrcatA(log_file, "\\msitest.log");
8950     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
8951
8952     test_MsiInstallProduct();
8953     test_MsiSetComponentState();
8954     test_packagecoltypes();
8955     test_continuouscabs();
8956     test_caborder();
8957     test_mixedmedia();
8958     test_samesequence();
8959     test_uiLevelFlags();
8960     test_readonlyfile();
8961     test_readonlyfile_cab();
8962     test_setdirproperty();
8963     test_cabisextracted();
8964     test_concurrentinstall();
8965     test_setpropertyfolder();
8966     test_publish_registerproduct();
8967     test_publish_publishproduct();
8968     test_publish_publishfeatures();
8969     test_publish_registeruser();
8970     test_publish_processcomponents();
8971     test_publish();
8972     test_publishsourcelist();
8973     test_transformprop();
8974     test_currentworkingdir();
8975     test_admin();
8976     test_adminprops();
8977     test_removefiles();
8978     test_movefiles();
8979     test_missingcab();
8980     test_duplicatefiles();
8981     test_writeregistryvalues();
8982     test_sourcefolder();
8983     test_customaction51();
8984     test_installstate();
8985     test_sourcepath();
8986     test_MsiConfigureProductEx();
8987     test_missingcomponent();
8988     test_sourcedirprop();
8989     test_adminimage();
8990     test_propcase();
8991     test_int_widths();
8992     test_shortcut();
8993     test_envvar();
8994     test_lastusedsource();
8995     test_preselected();
8996     test_installed_prop();
8997     test_file_in_use();
8998     test_file_in_use_cab();
8999     test_MsiSetExternalUI();
9000     test_allusers_prop();
9001     test_feature_override();
9002     test_create_folder();
9003     test_remove_folder();
9004     test_start_services();
9005     test_delete_services();
9006     test_self_registration();
9007     test_register_font();
9008     test_validate_product_id();
9009     test_install_remove_odbc();
9010     test_register_typelib();
9011     test_create_remove_shortcut();
9012     test_publish_components();
9013     test_remove_duplicate_files();
9014     test_remove_registry_values();
9015     test_find_related_products();
9016     test_remove_ini_values();
9017     test_remove_env_strings();
9018
9019     DeleteFileA(log_file);
9020
9021     if (pSRSetRestorePointA && ret)
9022     {
9023         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
9024         if (ret)
9025             remove_restore_point(status.llSequenceNumber);
9026     }
9027     FreeLibrary(hsrclient);
9028
9029     SetCurrentDirectoryA(prev_path);
9030 }