msi: Remove empty directories as part of the RemoveFiles action.
[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 typedef struct _msi_table
1556 {
1557     const CHAR *filename;
1558     const CHAR *data;
1559     int size;
1560 } msi_table;
1561
1562 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
1563
1564 static const msi_table tables[] =
1565 {
1566     ADD_TABLE(component),
1567     ADD_TABLE(directory),
1568     ADD_TABLE(feature),
1569     ADD_TABLE(feature_comp),
1570     ADD_TABLE(file),
1571     ADD_TABLE(install_exec_seq),
1572     ADD_TABLE(media),
1573     ADD_TABLE(property),
1574     ADD_TABLE(registry),
1575     ADD_TABLE(service_install),
1576     ADD_TABLE(service_control)
1577 };
1578
1579 static const msi_table sc_tables[] =
1580 {
1581     ADD_TABLE(component),
1582     ADD_TABLE(directory),
1583     ADD_TABLE(feature),
1584     ADD_TABLE(feature_comp),
1585     ADD_TABLE(file),
1586     ADD_TABLE(install_exec_seq),
1587     ADD_TABLE(media),
1588     ADD_TABLE(property),
1589     ADD_TABLE(shortcut)
1590 };
1591
1592 static const msi_table ps_tables[] =
1593 {
1594     ADD_TABLE(component),
1595     ADD_TABLE(directory),
1596     ADD_TABLE(feature),
1597     ADD_TABLE(feature_comp),
1598     ADD_TABLE(file),
1599     ADD_TABLE(install_exec_seq),
1600     ADD_TABLE(media),
1601     ADD_TABLE(property),
1602     ADD_TABLE(condition)
1603 };
1604
1605 static const msi_table env_tables[] =
1606 {
1607     ADD_TABLE(component),
1608     ADD_TABLE(directory),
1609     ADD_TABLE(feature),
1610     ADD_TABLE(feature_comp),
1611     ADD_TABLE(file),
1612     ADD_TABLE(install_exec_seq),
1613     ADD_TABLE(media),
1614     ADD_TABLE(property),
1615     ADD_TABLE(environment)
1616 };
1617
1618 static const msi_table up_tables[] =
1619 {
1620     ADD_TABLE(component),
1621     ADD_TABLE(directory),
1622     ADD_TABLE(feature),
1623     ADD_TABLE(feature_comp),
1624     ADD_TABLE(file),
1625     ADD_TABLE(install_exec_seq),
1626     ADD_TABLE(media),
1627     ADD_TABLE(up_property),
1628     ADD_TABLE(registry),
1629     ADD_TABLE(service_install),
1630     ADD_TABLE(service_control)
1631 };
1632
1633 static const msi_table up2_tables[] =
1634 {
1635     ADD_TABLE(component),
1636     ADD_TABLE(directory),
1637     ADD_TABLE(feature),
1638     ADD_TABLE(feature_comp),
1639     ADD_TABLE(file),
1640     ADD_TABLE(install_exec_seq),
1641     ADD_TABLE(media),
1642     ADD_TABLE(up2_property),
1643     ADD_TABLE(registry),
1644     ADD_TABLE(service_install),
1645     ADD_TABLE(service_control)
1646 };
1647
1648 static const msi_table up3_tables[] =
1649 {
1650     ADD_TABLE(component),
1651     ADD_TABLE(directory),
1652     ADD_TABLE(feature),
1653     ADD_TABLE(feature_comp),
1654     ADD_TABLE(file),
1655     ADD_TABLE(install_exec_seq),
1656     ADD_TABLE(media),
1657     ADD_TABLE(up3_property),
1658     ADD_TABLE(registry),
1659     ADD_TABLE(service_install),
1660     ADD_TABLE(service_control)
1661 };
1662
1663 static const msi_table up4_tables[] =
1664 {
1665     ADD_TABLE(component),
1666     ADD_TABLE(directory),
1667     ADD_TABLE(feature),
1668     ADD_TABLE(feature_comp),
1669     ADD_TABLE(file),
1670     ADD_TABLE(pp_install_exec_seq),
1671     ADD_TABLE(media),
1672     ADD_TABLE(property),
1673     ADD_TABLE(registry),
1674     ADD_TABLE(service_install),
1675     ADD_TABLE(service_control)
1676 };
1677
1678 static const msi_table up5_tables[] =
1679 {
1680     ADD_TABLE(component),
1681     ADD_TABLE(directory),
1682     ADD_TABLE(feature),
1683     ADD_TABLE(feature_comp),
1684     ADD_TABLE(file),
1685     ADD_TABLE(pp_install_exec_seq),
1686     ADD_TABLE(media),
1687     ADD_TABLE(up_property),
1688     ADD_TABLE(registry),
1689     ADD_TABLE(service_install),
1690     ADD_TABLE(service_control)
1691 };
1692
1693 static const msi_table up6_tables[] =
1694 {
1695     ADD_TABLE(component),
1696     ADD_TABLE(directory),
1697     ADD_TABLE(feature),
1698     ADD_TABLE(feature_comp),
1699     ADD_TABLE(file),
1700     ADD_TABLE(pp_install_exec_seq),
1701     ADD_TABLE(media),
1702     ADD_TABLE(up2_property),
1703     ADD_TABLE(registry),
1704     ADD_TABLE(service_install),
1705     ADD_TABLE(service_control)
1706 };
1707
1708 static const msi_table up7_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(pp_install_exec_seq),
1716     ADD_TABLE(media),
1717     ADD_TABLE(up3_property),
1718     ADD_TABLE(registry),
1719     ADD_TABLE(service_install),
1720     ADD_TABLE(service_control)
1721 };
1722
1723 static const msi_table cc_tables[] =
1724 {
1725     ADD_TABLE(cc_component),
1726     ADD_TABLE(directory),
1727     ADD_TABLE(cc_feature),
1728     ADD_TABLE(cc_feature_comp),
1729     ADD_TABLE(cc_file),
1730     ADD_TABLE(install_exec_seq),
1731     ADD_TABLE(cc_media),
1732     ADD_TABLE(property),
1733 };
1734
1735 static const msi_table cc2_tables[] =
1736 {
1737     ADD_TABLE(cc2_component),
1738     ADD_TABLE(directory),
1739     ADD_TABLE(cc_feature),
1740     ADD_TABLE(cc_feature_comp),
1741     ADD_TABLE(cc2_file),
1742     ADD_TABLE(install_exec_seq),
1743     ADD_TABLE(cc_media),
1744     ADD_TABLE(property),
1745 };
1746
1747 static const msi_table co_tables[] =
1748 {
1749     ADD_TABLE(cc_component),
1750     ADD_TABLE(directory),
1751     ADD_TABLE(cc_feature),
1752     ADD_TABLE(cc_feature_comp),
1753     ADD_TABLE(co_file),
1754     ADD_TABLE(install_exec_seq),
1755     ADD_TABLE(co_media),
1756     ADD_TABLE(property),
1757 };
1758
1759 static const msi_table co2_tables[] =
1760 {
1761     ADD_TABLE(cc_component),
1762     ADD_TABLE(directory),
1763     ADD_TABLE(cc_feature),
1764     ADD_TABLE(cc_feature_comp),
1765     ADD_TABLE(cc_file),
1766     ADD_TABLE(install_exec_seq),
1767     ADD_TABLE(co2_media),
1768     ADD_TABLE(property),
1769 };
1770
1771 static const msi_table mm_tables[] =
1772 {
1773     ADD_TABLE(cc_component),
1774     ADD_TABLE(directory),
1775     ADD_TABLE(cc_feature),
1776     ADD_TABLE(cc_feature_comp),
1777     ADD_TABLE(mm_file),
1778     ADD_TABLE(install_exec_seq),
1779     ADD_TABLE(mm_media),
1780     ADD_TABLE(property),
1781 };
1782
1783 static const msi_table ss_tables[] =
1784 {
1785     ADD_TABLE(cc_component),
1786     ADD_TABLE(directory),
1787     ADD_TABLE(cc_feature),
1788     ADD_TABLE(cc_feature_comp),
1789     ADD_TABLE(cc_file),
1790     ADD_TABLE(install_exec_seq),
1791     ADD_TABLE(ss_media),
1792     ADD_TABLE(property),
1793 };
1794
1795 static const msi_table ui_tables[] =
1796 {
1797     ADD_TABLE(ui_component),
1798     ADD_TABLE(directory),
1799     ADD_TABLE(cc_feature),
1800     ADD_TABLE(cc_feature_comp),
1801     ADD_TABLE(cc_file),
1802     ADD_TABLE(install_exec_seq),
1803     ADD_TABLE(ui_install_ui_seq),
1804     ADD_TABLE(ui_custom_action),
1805     ADD_TABLE(cc_media),
1806     ADD_TABLE(property),
1807 };
1808
1809 static const msi_table rof_tables[] =
1810 {
1811     ADD_TABLE(rof_component),
1812     ADD_TABLE(directory),
1813     ADD_TABLE(rof_feature),
1814     ADD_TABLE(rof_feature_comp),
1815     ADD_TABLE(rof_file),
1816     ADD_TABLE(install_exec_seq),
1817     ADD_TABLE(rof_media),
1818     ADD_TABLE(property),
1819 };
1820
1821 static const msi_table rofc_tables[] =
1822 {
1823     ADD_TABLE(rof_component),
1824     ADD_TABLE(directory),
1825     ADD_TABLE(rof_feature),
1826     ADD_TABLE(rof_feature_comp),
1827     ADD_TABLE(rofc_file),
1828     ADD_TABLE(install_exec_seq),
1829     ADD_TABLE(rofc_media),
1830     ADD_TABLE(property),
1831 };
1832
1833 static const msi_table sdp_tables[] =
1834 {
1835     ADD_TABLE(rof_component),
1836     ADD_TABLE(directory),
1837     ADD_TABLE(rof_feature),
1838     ADD_TABLE(rof_feature_comp),
1839     ADD_TABLE(rof_file),
1840     ADD_TABLE(sdp_install_exec_seq),
1841     ADD_TABLE(sdp_custom_action),
1842     ADD_TABLE(rof_media),
1843     ADD_TABLE(property),
1844 };
1845
1846 static const msi_table cie_tables[] =
1847 {
1848     ADD_TABLE(cie_component),
1849     ADD_TABLE(directory),
1850     ADD_TABLE(cc_feature),
1851     ADD_TABLE(cie_feature_comp),
1852     ADD_TABLE(cie_file),
1853     ADD_TABLE(install_exec_seq),
1854     ADD_TABLE(cie_media),
1855     ADD_TABLE(property),
1856 };
1857
1858 static const msi_table ci_tables[] =
1859 {
1860     ADD_TABLE(ci_component),
1861     ADD_TABLE(directory),
1862     ADD_TABLE(rof_feature),
1863     ADD_TABLE(rof_feature_comp),
1864     ADD_TABLE(rof_file),
1865     ADD_TABLE(ci_install_exec_seq),
1866     ADD_TABLE(rof_media),
1867     ADD_TABLE(property),
1868     ADD_TABLE(ci_custom_action),
1869 };
1870
1871 static const msi_table ci2_tables[] =
1872 {
1873     ADD_TABLE(ci2_component),
1874     ADD_TABLE(directory),
1875     ADD_TABLE(rof_feature),
1876     ADD_TABLE(ci2_feature_comp),
1877     ADD_TABLE(ci2_file),
1878     ADD_TABLE(install_exec_seq),
1879     ADD_TABLE(rof_media),
1880     ADD_TABLE(property),
1881 };
1882
1883 static const msi_table spf_tables[] =
1884 {
1885     ADD_TABLE(ci_component),
1886     ADD_TABLE(directory),
1887     ADD_TABLE(rof_feature),
1888     ADD_TABLE(rof_feature_comp),
1889     ADD_TABLE(rof_file),
1890     ADD_TABLE(spf_install_exec_seq),
1891     ADD_TABLE(rof_media),
1892     ADD_TABLE(property),
1893     ADD_TABLE(spf_custom_action),
1894     ADD_TABLE(spf_install_ui_seq),
1895 };
1896
1897 static const msi_table pp_tables[] =
1898 {
1899     ADD_TABLE(ci_component),
1900     ADD_TABLE(directory),
1901     ADD_TABLE(rof_feature),
1902     ADD_TABLE(rof_feature_comp),
1903     ADD_TABLE(rof_file),
1904     ADD_TABLE(pp_install_exec_seq),
1905     ADD_TABLE(rof_media),
1906     ADD_TABLE(property),
1907 };
1908
1909 static const msi_table ppc_tables[] =
1910 {
1911     ADD_TABLE(ppc_component),
1912     ADD_TABLE(directory),
1913     ADD_TABLE(rof_feature),
1914     ADD_TABLE(ppc_feature_comp),
1915     ADD_TABLE(ppc_file),
1916     ADD_TABLE(pp_install_exec_seq),
1917     ADD_TABLE(ppc_media),
1918     ADD_TABLE(property),
1919 };
1920
1921 static const msi_table lus0_tables[] =
1922 {
1923     ADD_TABLE(ci_component),
1924     ADD_TABLE(directory),
1925     ADD_TABLE(rof_feature),
1926     ADD_TABLE(rof_feature_comp),
1927     ADD_TABLE(rof_file),
1928     ADD_TABLE(pp_install_exec_seq),
1929     ADD_TABLE(rof_media),
1930     ADD_TABLE(property),
1931 };
1932
1933 static const msi_table lus1_tables[] =
1934 {
1935     ADD_TABLE(ci_component),
1936     ADD_TABLE(directory),
1937     ADD_TABLE(rof_feature),
1938     ADD_TABLE(rof_feature_comp),
1939     ADD_TABLE(rof_file),
1940     ADD_TABLE(pp_install_exec_seq),
1941     ADD_TABLE(rofc_media),
1942     ADD_TABLE(property),
1943 };
1944
1945 static const msi_table lus2_tables[] =
1946 {
1947     ADD_TABLE(ci_component),
1948     ADD_TABLE(directory),
1949     ADD_TABLE(rof_feature),
1950     ADD_TABLE(rof_feature_comp),
1951     ADD_TABLE(rof_file),
1952     ADD_TABLE(pp_install_exec_seq),
1953     ADD_TABLE(lus2_media),
1954     ADD_TABLE(property),
1955 };
1956
1957 static const msi_table tp_tables[] =
1958 {
1959     ADD_TABLE(tp_component),
1960     ADD_TABLE(directory),
1961     ADD_TABLE(rof_feature),
1962     ADD_TABLE(ci2_feature_comp),
1963     ADD_TABLE(ci2_file),
1964     ADD_TABLE(install_exec_seq),
1965     ADD_TABLE(rof_media),
1966     ADD_TABLE(property),
1967 };
1968
1969 static const msi_table cwd_tables[] =
1970 {
1971     ADD_TABLE(cwd_component),
1972     ADD_TABLE(directory),
1973     ADD_TABLE(rof_feature),
1974     ADD_TABLE(ci2_feature_comp),
1975     ADD_TABLE(ci2_file),
1976     ADD_TABLE(install_exec_seq),
1977     ADD_TABLE(rof_media),
1978     ADD_TABLE(property),
1979 };
1980
1981 static const msi_table adm_tables[] =
1982 {
1983     ADD_TABLE(adm_component),
1984     ADD_TABLE(directory),
1985     ADD_TABLE(rof_feature),
1986     ADD_TABLE(ci2_feature_comp),
1987     ADD_TABLE(ci2_file),
1988     ADD_TABLE(install_exec_seq),
1989     ADD_TABLE(rof_media),
1990     ADD_TABLE(property),
1991     ADD_TABLE(adm_custom_action),
1992     ADD_TABLE(adm_admin_exec_seq),
1993 };
1994
1995 static const msi_table amp_tables[] =
1996 {
1997     ADD_TABLE(amp_component),
1998     ADD_TABLE(directory),
1999     ADD_TABLE(rof_feature),
2000     ADD_TABLE(ci2_feature_comp),
2001     ADD_TABLE(ci2_file),
2002     ADD_TABLE(install_exec_seq),
2003     ADD_TABLE(rof_media),
2004     ADD_TABLE(property),
2005 };
2006
2007 static const msi_table rem_tables[] =
2008 {
2009     ADD_TABLE(rem_component),
2010     ADD_TABLE(directory),
2011     ADD_TABLE(rof_feature),
2012     ADD_TABLE(rem_feature_comp),
2013     ADD_TABLE(rem_file),
2014     ADD_TABLE(rem_install_exec_seq),
2015     ADD_TABLE(rof_media),
2016     ADD_TABLE(property),
2017     ADD_TABLE(rem_remove_files),
2018 };
2019
2020 static const msi_table mov_tables[] =
2021 {
2022     ADD_TABLE(cwd_component),
2023     ADD_TABLE(directory),
2024     ADD_TABLE(rof_feature),
2025     ADD_TABLE(ci2_feature_comp),
2026     ADD_TABLE(ci2_file),
2027     ADD_TABLE(install_exec_seq),
2028     ADD_TABLE(rof_media),
2029     ADD_TABLE(property),
2030     ADD_TABLE(mov_move_file),
2031 };
2032
2033 static const msi_table mc_tables[] =
2034 {
2035     ADD_TABLE(mc_component),
2036     ADD_TABLE(directory),
2037     ADD_TABLE(cc_feature),
2038     ADD_TABLE(cie_feature_comp),
2039     ADD_TABLE(mc_file),
2040     ADD_TABLE(install_exec_seq),
2041     ADD_TABLE(mc_media),
2042     ADD_TABLE(property),
2043     ADD_TABLE(mc_file_hash),
2044 };
2045
2046 static const msi_table df_tables[] =
2047 {
2048     ADD_TABLE(rof_component),
2049     ADD_TABLE(df_directory),
2050     ADD_TABLE(rof_feature),
2051     ADD_TABLE(rof_feature_comp),
2052     ADD_TABLE(rof_file),
2053     ADD_TABLE(install_exec_seq),
2054     ADD_TABLE(rof_media),
2055     ADD_TABLE(property),
2056     ADD_TABLE(df_duplicate_file),
2057 };
2058
2059 static const msi_table wrv_tables[] =
2060 {
2061     ADD_TABLE(wrv_component),
2062     ADD_TABLE(directory),
2063     ADD_TABLE(rof_feature),
2064     ADD_TABLE(ci2_feature_comp),
2065     ADD_TABLE(ci2_file),
2066     ADD_TABLE(install_exec_seq),
2067     ADD_TABLE(rof_media),
2068     ADD_TABLE(property),
2069     ADD_TABLE(wrv_registry),
2070 };
2071
2072 static const msi_table sf_tables[] =
2073 {
2074     ADD_TABLE(wrv_component),
2075     ADD_TABLE(directory),
2076     ADD_TABLE(rof_feature),
2077     ADD_TABLE(ci2_feature_comp),
2078     ADD_TABLE(ci2_file),
2079     ADD_TABLE(install_exec_seq),
2080     ADD_TABLE(rof_media),
2081     ADD_TABLE(property),
2082 };
2083
2084 static const msi_table ca51_tables[] =
2085 {
2086     ADD_TABLE(ca51_component),
2087     ADD_TABLE(directory),
2088     ADD_TABLE(rof_feature),
2089     ADD_TABLE(ci2_feature_comp),
2090     ADD_TABLE(ci2_file),
2091     ADD_TABLE(ca51_install_exec_seq),
2092     ADD_TABLE(rof_media),
2093     ADD_TABLE(property),
2094     ADD_TABLE(ca51_custom_action),
2095 };
2096
2097 static const msi_table is_tables[] =
2098 {
2099     ADD_TABLE(is_component),
2100     ADD_TABLE(directory),
2101     ADD_TABLE(is_feature),
2102     ADD_TABLE(is_feature_comp),
2103     ADD_TABLE(is_file),
2104     ADD_TABLE(install_exec_seq),
2105     ADD_TABLE(is_media),
2106     ADD_TABLE(property),
2107 };
2108
2109 static const msi_table sp_tables[] =
2110 {
2111     ADD_TABLE(sp_component),
2112     ADD_TABLE(sp_directory),
2113     ADD_TABLE(rof_feature),
2114     ADD_TABLE(ci2_feature_comp),
2115     ADD_TABLE(ci2_file),
2116     ADD_TABLE(install_exec_seq),
2117     ADD_TABLE(rof_media),
2118     ADD_TABLE(property),
2119 };
2120
2121 static const msi_table mcp_tables[] =
2122 {
2123     ADD_TABLE(mcp_component),
2124     ADD_TABLE(directory),
2125     ADD_TABLE(mcp_feature),
2126     ADD_TABLE(mcp_feature_comp),
2127     ADD_TABLE(rem_file),
2128     ADD_TABLE(rem_install_exec_seq),
2129     ADD_TABLE(rof_media),
2130     ADD_TABLE(property),
2131 };
2132
2133 static const msi_table mcomp_tables[] =
2134 {
2135     ADD_TABLE(mcp_component),
2136     ADD_TABLE(directory),
2137     ADD_TABLE(mcp_feature),
2138     ADD_TABLE(mcp_feature_comp),
2139     ADD_TABLE(mcomp_file),
2140     ADD_TABLE(rem_install_exec_seq),
2141     ADD_TABLE(rof_media),
2142     ADD_TABLE(property),
2143 };
2144
2145 static const msi_table ai_tables[] =
2146 {
2147     ADD_TABLE(component),
2148     ADD_TABLE(directory),
2149     ADD_TABLE(feature),
2150     ADD_TABLE(feature_comp),
2151     ADD_TABLE(ai_file),
2152     ADD_TABLE(install_exec_seq),
2153     ADD_TABLE(media),
2154     ADD_TABLE(property)
2155 };
2156
2157 static const msi_table pc_tables[] =
2158 {
2159     ADD_TABLE(ca51_component),
2160     ADD_TABLE(directory),
2161     ADD_TABLE(rof_feature),
2162     ADD_TABLE(ci2_feature_comp),
2163     ADD_TABLE(ci2_file),
2164     ADD_TABLE(install_exec_seq),
2165     ADD_TABLE(rof_media),
2166     ADD_TABLE(property)
2167 };
2168
2169 static const msi_table ip_tables[] =
2170 {
2171     ADD_TABLE(component),
2172     ADD_TABLE(directory),
2173     ADD_TABLE(feature),
2174     ADD_TABLE(feature_comp),
2175     ADD_TABLE(file),
2176     ADD_TABLE(ip_install_exec_seq),
2177     ADD_TABLE(ip_custom_action),
2178     ADD_TABLE(media),
2179     ADD_TABLE(property)
2180 };
2181
2182 static const msi_table aup_tables[] =
2183 {
2184     ADD_TABLE(component),
2185     ADD_TABLE(directory),
2186     ADD_TABLE(feature),
2187     ADD_TABLE(feature_comp),
2188     ADD_TABLE(file),
2189     ADD_TABLE(aup_install_exec_seq),
2190     ADD_TABLE(aup_custom_action),
2191     ADD_TABLE(media),
2192     ADD_TABLE(property)
2193 };
2194
2195 static const msi_table aup2_tables[] =
2196 {
2197     ADD_TABLE(component),
2198     ADD_TABLE(directory),
2199     ADD_TABLE(feature),
2200     ADD_TABLE(feature_comp),
2201     ADD_TABLE(file),
2202     ADD_TABLE(aup2_install_exec_seq),
2203     ADD_TABLE(aup_custom_action),
2204     ADD_TABLE(media),
2205     ADD_TABLE(aup_property)
2206 };
2207
2208 static const msi_table aup3_tables[] =
2209 {
2210     ADD_TABLE(component),
2211     ADD_TABLE(directory),
2212     ADD_TABLE(feature),
2213     ADD_TABLE(feature_comp),
2214     ADD_TABLE(file),
2215     ADD_TABLE(aup2_install_exec_seq),
2216     ADD_TABLE(aup_custom_action),
2217     ADD_TABLE(media),
2218     ADD_TABLE(aup2_property)
2219 };
2220
2221 static const msi_table aup4_tables[] =
2222 {
2223     ADD_TABLE(component),
2224     ADD_TABLE(directory),
2225     ADD_TABLE(feature),
2226     ADD_TABLE(feature_comp),
2227     ADD_TABLE(file),
2228     ADD_TABLE(aup3_install_exec_seq),
2229     ADD_TABLE(aup_custom_action),
2230     ADD_TABLE(media),
2231     ADD_TABLE(aup2_property)
2232 };
2233
2234 static const msi_table fiu_tables[] =
2235 {
2236     ADD_TABLE(rof_component),
2237     ADD_TABLE(directory),
2238     ADD_TABLE(rof_feature),
2239     ADD_TABLE(rof_feature_comp),
2240     ADD_TABLE(rof_file),
2241     ADD_TABLE(pp_install_exec_seq),
2242     ADD_TABLE(rof_media),
2243     ADD_TABLE(property),
2244 };
2245
2246 static const msi_table fiuc_tables[] =
2247 {
2248     ADD_TABLE(rof_component),
2249     ADD_TABLE(directory),
2250     ADD_TABLE(rof_feature),
2251     ADD_TABLE(rof_feature_comp),
2252     ADD_TABLE(rofc_file),
2253     ADD_TABLE(pp_install_exec_seq),
2254     ADD_TABLE(rofc_media),
2255     ADD_TABLE(property),
2256 };
2257
2258 static const msi_table cf_tables[] =
2259 {
2260     ADD_TABLE(component),
2261     ADD_TABLE(directory),
2262     ADD_TABLE(feature),
2263     ADD_TABLE(feature_comp),
2264     ADD_TABLE(file),
2265     ADD_TABLE(cf_create_folders),
2266     ADD_TABLE(cf_install_exec_seq),
2267     ADD_TABLE(cf_custom_action),
2268     ADD_TABLE(media),
2269     ADD_TABLE(property)
2270 };
2271
2272 static const msi_table rf_tables[] =
2273 {
2274     ADD_TABLE(component),
2275     ADD_TABLE(directory),
2276     ADD_TABLE(feature),
2277     ADD_TABLE(feature_comp),
2278     ADD_TABLE(file),
2279     ADD_TABLE(cf_create_folders),
2280     ADD_TABLE(rf_install_exec_seq),
2281     ADD_TABLE(cf_custom_action),
2282     ADD_TABLE(media),
2283     ADD_TABLE(property)
2284 };
2285
2286 static const msi_table sss_tables[] =
2287 {
2288     ADD_TABLE(component),
2289     ADD_TABLE(directory),
2290     ADD_TABLE(feature),
2291     ADD_TABLE(feature_comp),
2292     ADD_TABLE(file),
2293     ADD_TABLE(sss_install_exec_seq),
2294     ADD_TABLE(sss_service_control),
2295     ADD_TABLE(media),
2296     ADD_TABLE(property)
2297 };
2298
2299 static const msi_table sds_tables[] =
2300 {
2301     ADD_TABLE(component),
2302     ADD_TABLE(directory),
2303     ADD_TABLE(feature),
2304     ADD_TABLE(feature_comp),
2305     ADD_TABLE(file),
2306     ADD_TABLE(sss_install_exec_seq),
2307     ADD_TABLE(service_control),
2308     ADD_TABLE(media),
2309     ADD_TABLE(property)
2310 };
2311
2312 static const msi_table sr_tables[] =
2313 {
2314     ADD_TABLE(component),
2315     ADD_TABLE(directory),
2316     ADD_TABLE(feature),
2317     ADD_TABLE(feature_comp),
2318     ADD_TABLE(file),
2319     ADD_TABLE(sr_selfreg),
2320     ADD_TABLE(sr_install_exec_seq),
2321     ADD_TABLE(media),
2322     ADD_TABLE(property)
2323 };
2324
2325 static const msi_table font_tables[] =
2326 {
2327     ADD_TABLE(font_component),
2328     ADD_TABLE(directory),
2329     ADD_TABLE(font_feature),
2330     ADD_TABLE(font_feature_comp),
2331     ADD_TABLE(font_file),
2332     ADD_TABLE(font),
2333     ADD_TABLE(font_install_exec_seq),
2334     ADD_TABLE(font_media),
2335     ADD_TABLE(property)
2336 };
2337
2338 static const msi_table vp_tables[] =
2339 {
2340     ADD_TABLE(component),
2341     ADD_TABLE(directory),
2342     ADD_TABLE(feature),
2343     ADD_TABLE(feature_comp),
2344     ADD_TABLE(file),
2345     ADD_TABLE(vp_custom_action),
2346     ADD_TABLE(vp_install_exec_seq),
2347     ADD_TABLE(media),
2348     ADD_TABLE(vp_property)
2349 };
2350
2351 static const msi_table odbc_tables[] =
2352 {
2353     ADD_TABLE(odbc_component),
2354     ADD_TABLE(directory),
2355     ADD_TABLE(odbc_feature),
2356     ADD_TABLE(odbc_feature_comp),
2357     ADD_TABLE(odbc_file),
2358     ADD_TABLE(odbc_driver),
2359     ADD_TABLE(odbc_translator),
2360     ADD_TABLE(odbc_datasource),
2361     ADD_TABLE(odbc_install_exec_seq),
2362     ADD_TABLE(odbc_media),
2363     ADD_TABLE(property)
2364 };
2365
2366 static const msi_table tl_tables[] =
2367 {
2368     ADD_TABLE(tl_component),
2369     ADD_TABLE(directory),
2370     ADD_TABLE(tl_feature),
2371     ADD_TABLE(tl_feature_comp),
2372     ADD_TABLE(tl_file),
2373     ADD_TABLE(tl_typelib),
2374     ADD_TABLE(tl_install_exec_seq),
2375     ADD_TABLE(media),
2376     ADD_TABLE(property)
2377 };
2378
2379 static const msi_table crs_tables[] =
2380 {
2381     ADD_TABLE(crs_component),
2382     ADD_TABLE(directory),
2383     ADD_TABLE(crs_feature),
2384     ADD_TABLE(crs_feature_comp),
2385     ADD_TABLE(crs_file),
2386     ADD_TABLE(crs_shortcut),
2387     ADD_TABLE(crs_install_exec_seq),
2388     ADD_TABLE(media),
2389     ADD_TABLE(property)
2390 };
2391
2392 static const msi_table pub_tables[] =
2393 {
2394     ADD_TABLE(directory),
2395     ADD_TABLE(pub_component),
2396     ADD_TABLE(pub_feature),
2397     ADD_TABLE(pub_feature_comp),
2398     ADD_TABLE(pub_file),
2399     ADD_TABLE(pub_publish_component),
2400     ADD_TABLE(pub_install_exec_seq),
2401     ADD_TABLE(media),
2402     ADD_TABLE(property)
2403 };
2404
2405 static const msi_table rd_tables[] =
2406 {
2407     ADD_TABLE(directory),
2408     ADD_TABLE(rd_component),
2409     ADD_TABLE(rd_feature),
2410     ADD_TABLE(rd_feature_comp),
2411     ADD_TABLE(rd_file),
2412     ADD_TABLE(rd_duplicate_file),
2413     ADD_TABLE(rd_install_exec_seq),
2414     ADD_TABLE(media),
2415     ADD_TABLE(property)
2416 };
2417
2418 static const msi_table rrv_tables[] =
2419 {
2420     ADD_TABLE(directory),
2421     ADD_TABLE(rrv_component),
2422     ADD_TABLE(rrv_feature),
2423     ADD_TABLE(rrv_feature_comp),
2424     ADD_TABLE(rrv_file),
2425     ADD_TABLE(rrv_registry),
2426     ADD_TABLE(rrv_remove_registry),
2427     ADD_TABLE(rrv_install_exec_seq),
2428     ADD_TABLE(media),
2429     ADD_TABLE(property)
2430 };
2431
2432 /* cabinet definitions */
2433
2434 /* make the max size large so there is only one cab file */
2435 #define MEDIA_SIZE          0x7FFFFFFF
2436 #define FOLDER_THRESHOLD    900000
2437
2438 /* the FCI callbacks */
2439
2440 static void * CDECL mem_alloc(ULONG cb)
2441 {
2442     return HeapAlloc(GetProcessHeap(), 0, cb);
2443 }
2444
2445 static void CDECL mem_free(void *memory)
2446 {
2447     HeapFree(GetProcessHeap(), 0, memory);
2448 }
2449
2450 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
2451 {
2452     sprintf(pccab->szCab, pv, pccab->iCab);
2453     return TRUE;
2454 }
2455
2456 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
2457 {
2458     return 0;
2459 }
2460
2461 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
2462                              BOOL fContinuation, void *pv)
2463 {
2464     return 0;
2465 }
2466
2467 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
2468 {
2469     HANDLE handle;
2470     DWORD dwAccess = 0;
2471     DWORD dwShareMode = 0;
2472     DWORD dwCreateDisposition = OPEN_EXISTING;
2473     
2474     dwAccess = GENERIC_READ | GENERIC_WRITE;
2475     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
2476     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
2477
2478     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
2479         dwCreateDisposition = OPEN_EXISTING;
2480     else
2481         dwCreateDisposition = CREATE_NEW;
2482
2483     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
2484                          dwCreateDisposition, 0, NULL);
2485
2486     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
2487
2488     return (INT_PTR)handle;
2489 }
2490
2491 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2492 {
2493     HANDLE handle = (HANDLE)hf;
2494     DWORD dwRead;
2495     BOOL res;
2496     
2497     res = ReadFile(handle, memory, cb, &dwRead, NULL);
2498     ok(res, "Failed to ReadFile\n");
2499
2500     return dwRead;
2501 }
2502
2503 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2504 {
2505     HANDLE handle = (HANDLE)hf;
2506     DWORD dwWritten;
2507     BOOL res;
2508
2509     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
2510     ok(res, "Failed to WriteFile\n");
2511
2512     return dwWritten;
2513 }
2514
2515 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
2516 {
2517     HANDLE handle = (HANDLE)hf;
2518     ok(CloseHandle(handle), "Failed to CloseHandle\n");
2519
2520     return 0;
2521 }
2522
2523 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
2524 {
2525     HANDLE handle = (HANDLE)hf;
2526     DWORD ret;
2527     
2528     ret = SetFilePointer(handle, dist, NULL, seektype);
2529     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
2530
2531     return ret;
2532 }
2533
2534 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
2535 {
2536     BOOL ret = DeleteFileA(pszFile);
2537     ok(ret, "Failed to DeleteFile %s\n", pszFile);
2538
2539     return 0;
2540 }
2541
2542 static void init_functionpointers(void)
2543 {
2544     HMODULE hmsi = GetModuleHandleA("msi.dll");
2545     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
2546
2547 #define GET_PROC(mod, func) \
2548     p ## func = (void*)GetProcAddress(mod, #func); \
2549     if(!p ## func) \
2550       trace("GetProcAddress(%s) failed\n", #func);
2551
2552     GET_PROC(hmsi, MsiQueryComponentStateA);
2553     GET_PROC(hmsi, MsiSetExternalUIRecord);
2554     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
2555     GET_PROC(hmsi, MsiSourceListGetInfoA);
2556
2557     GET_PROC(hadvapi32, ConvertSidToStringSidA);
2558
2559     hsrclient = LoadLibraryA("srclient.dll");
2560     GET_PROC(hsrclient, SRRemoveRestorePoint);
2561     GET_PROC(hsrclient, SRSetRestorePointA);
2562
2563 #undef GET_PROC
2564 }
2565
2566 static BOOL check_win9x(void)
2567 {
2568     SC_HANDLE scm;
2569
2570     scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
2571     if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2572         return TRUE;
2573
2574     CloseServiceHandle(scm);
2575
2576     return FALSE;
2577 }
2578
2579 static LPSTR get_user_sid(LPSTR *usersid)
2580 {
2581     HANDLE token;
2582     BYTE buf[1024];
2583     DWORD size;
2584     PTOKEN_USER user;
2585
2586     if (!pConvertSidToStringSidA)
2587     {
2588         win_skip("ConvertSidToStringSidA is not available\n");
2589         return NULL;
2590     }
2591
2592     *usersid = NULL;
2593     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
2594     size = sizeof(buf);
2595     GetTokenInformation(token, TokenUser, buf, size, &size);
2596     user = (PTOKEN_USER)buf;
2597     pConvertSidToStringSidA(user->User.Sid, usersid);
2598     ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError());
2599     CloseHandle(token);
2600     return *usersid;
2601 }
2602
2603 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
2604 {
2605     CHAR buffer[0x20];
2606     UINT r;
2607     DWORD sz;
2608
2609     sz = sizeof buffer;
2610     r = MsiRecordGetString(rec, field, buffer, &sz);
2611     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
2612 }
2613
2614 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
2615 {
2616     LPSTR tempname;
2617
2618     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2619     GetTempFileNameA(".", "xx", 0, tempname);
2620
2621     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
2622     {
2623         lstrcpyA(pszTempName, tempname);
2624         HeapFree(GetProcessHeap(), 0, tempname);
2625         return TRUE;
2626     }
2627
2628     HeapFree(GetProcessHeap(), 0, tempname);
2629
2630     return FALSE;
2631 }
2632
2633 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
2634                                    USHORT *pattribs, int *err, void *pv)
2635 {
2636     BY_HANDLE_FILE_INFORMATION finfo;
2637     FILETIME filetime;
2638     HANDLE handle;
2639     DWORD attrs;
2640     BOOL res;
2641
2642     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
2643                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
2644
2645     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
2646
2647     res = GetFileInformationByHandle(handle, &finfo);
2648     ok(res, "Expected GetFileInformationByHandle to succeed\n");
2649    
2650     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
2651     FileTimeToDosDateTime(&filetime, pdate, ptime);
2652
2653     attrs = GetFileAttributes(pszName);
2654     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
2655
2656     return (INT_PTR)handle;
2657 }
2658
2659 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
2660 {
2661     char path[MAX_PATH];
2662     char filename[MAX_PATH];
2663
2664     lstrcpyA(path, CURR_DIR);
2665     lstrcatA(path, "\\");
2666     lstrcatA(path, file);
2667
2668     lstrcpyA(filename, file);
2669
2670     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
2671                       progress, get_open_info, compress);
2672 }
2673
2674 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
2675 {
2676     ZeroMemory(pCabParams, sizeof(CCAB));
2677
2678     pCabParams->cb = max_size;
2679     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
2680     pCabParams->setID = 0xbeef;
2681     pCabParams->iCab = 1;
2682     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
2683     lstrcatA(pCabParams->szCabPath, "\\");
2684     lstrcpyA(pCabParams->szCab, name);
2685 }
2686
2687 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
2688 {
2689     CCAB cabParams;
2690     LPCSTR ptr;
2691     HFCI hfci;
2692     ERF erf;
2693     BOOL res;
2694
2695     set_cab_parameters(&cabParams, name, max_size);
2696
2697     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2698                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2699                       get_temp_file, &cabParams, NULL);
2700
2701     ok(hfci != NULL, "Failed to create an FCI context\n");
2702
2703     ptr = files;
2704     while (*ptr)
2705     {
2706         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
2707         ok(res, "Failed to add file: %s\n", ptr);
2708         ptr += lstrlen(ptr) + 1;
2709     }
2710
2711     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2712     ok(res, "Failed to flush the cabinet\n");
2713
2714     res = FCIDestroy(hfci);
2715     ok(res, "Failed to destroy the cabinet\n");
2716 }
2717
2718 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
2719 {
2720     HKEY hkey;
2721     DWORD type, size;
2722
2723     if (RegOpenKey(HKEY_LOCAL_MACHINE,
2724                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
2725         return FALSE;
2726
2727     size = MAX_PATH;
2728     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
2729         RegCloseKey(hkey);
2730         return FALSE;
2731     }
2732
2733     size = MAX_PATH;
2734     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
2735         RegCloseKey(hkey);
2736         return FALSE;
2737     }
2738
2739     RegCloseKey(hkey);
2740     return TRUE;
2741 }
2742
2743 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
2744 {
2745     HANDLE file;
2746     DWORD written;
2747
2748     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2749     if (file == INVALID_HANDLE_VALUE)
2750         return;
2751
2752     WriteFile(file, data, strlen(data), &written, NULL);
2753
2754     if (size)
2755     {
2756         SetFilePointer(file, size, NULL, FILE_BEGIN);
2757         SetEndOfFile(file);
2758     }
2759
2760     CloseHandle(file);
2761 }
2762
2763 #define create_file(name, size) create_file_data(name, name, size)
2764
2765 static void create_test_files(void)
2766 {
2767     CreateDirectoryA("msitest", NULL);
2768     create_file("msitest\\one.txt", 100);
2769     CreateDirectoryA("msitest\\first", NULL);
2770     create_file("msitest\\first\\two.txt", 100);
2771     CreateDirectoryA("msitest\\second", NULL);
2772     create_file("msitest\\second\\three.txt", 100);
2773
2774     create_file("four.txt", 100);
2775     create_file("five.txt", 100);
2776     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
2777
2778     create_file("msitest\\filename", 100);
2779     create_file("msitest\\service.exe", 100);
2780
2781     DeleteFileA("four.txt");
2782     DeleteFileA("five.txt");
2783 }
2784
2785 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
2786 {
2787     CHAR path[MAX_PATH];
2788
2789     lstrcpyA(path, PROG_FILES_DIR);
2790     lstrcatA(path, "\\");
2791     lstrcatA(path, rel_path);
2792
2793     if (is_file)
2794         return DeleteFileA(path);
2795     else
2796         return RemoveDirectoryA(path);
2797 }
2798
2799 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
2800 {
2801     CHAR path[MAX_PATH];
2802
2803     lstrcpyA(path, COMMON_FILES_DIR);
2804     lstrcatA(path, "\\");
2805     lstrcatA(path, rel_path);
2806
2807     if (is_file)
2808         return DeleteFileA(path);
2809     else
2810         return RemoveDirectoryA(path);
2811 }
2812
2813 static void delete_test_files(void)
2814 {
2815     DeleteFileA("msitest.msi");
2816     DeleteFileA("msitest.cab");
2817     DeleteFileA("msitest\\second\\three.txt");
2818     DeleteFileA("msitest\\first\\two.txt");
2819     DeleteFileA("msitest\\one.txt");
2820     DeleteFileA("msitest\\service.exe");
2821     DeleteFileA("msitest\\filename");
2822     RemoveDirectoryA("msitest\\second");
2823     RemoveDirectoryA("msitest\\first");
2824     RemoveDirectoryA("msitest");
2825 }
2826
2827 static void write_file(const CHAR *filename, const char *data, int data_size)
2828 {
2829     DWORD size;
2830
2831     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
2832                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2833
2834     WriteFile(hf, data, data_size, &size, NULL);
2835     CloseHandle(hf);
2836 }
2837
2838 static void write_msi_summary_info(MSIHANDLE db, INT wordcount)
2839 {
2840     MSIHANDLE summary;
2841     UINT r;
2842
2843     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
2844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2845
2846     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
2847     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2848
2849     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2850                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
2851     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2852
2853     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
2854     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2855
2856     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
2857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2858
2859     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2860     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2861
2862     /* write the summary changes back to the stream */
2863     r = MsiSummaryInfoPersist(summary);
2864     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2865
2866     MsiCloseHandle(summary);
2867 }
2868
2869 #define create_database(name, tables, num_tables) \
2870     create_database_wordcount(name, tables, num_tables, 0);
2871
2872 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
2873                                       int num_tables, INT wordcount)
2874 {
2875     MSIHANDLE db;
2876     UINT r;
2877     int j;
2878
2879     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
2880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2881
2882     /* import the tables into the database */
2883     for (j = 0; j < num_tables; j++)
2884     {
2885         const msi_table *table = &tables[j];
2886
2887         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
2888
2889         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
2890         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2891
2892         DeleteFileA(table->filename);
2893     }
2894
2895     write_msi_summary_info(db, wordcount);
2896
2897     r = MsiDatabaseCommit(db);
2898     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2899
2900     MsiCloseHandle(db);
2901 }
2902
2903 static void check_service_is_installed(void)
2904 {
2905     SC_HANDLE scm, service;
2906     BOOL res;
2907
2908     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
2909     ok(scm != NULL, "Failed to open the SC Manager\n");
2910
2911     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
2912     ok(service != NULL, "Failed to open TestService\n");
2913
2914     res = DeleteService(service);
2915     ok(res, "Failed to delete TestService\n");
2916
2917     CloseServiceHandle(service);
2918     CloseServiceHandle(scm);
2919 }
2920
2921 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
2922 {
2923     RESTOREPOINTINFOA spec;
2924
2925     spec.dwEventType = event_type;
2926     spec.dwRestorePtType = APPLICATION_INSTALL;
2927     spec.llSequenceNumber = status->llSequenceNumber;
2928     lstrcpyA(spec.szDescription, "msitest restore point");
2929
2930     return pSRSetRestorePointA(&spec, status);
2931 }
2932
2933 static void remove_restore_point(DWORD seq_number)
2934 {
2935     DWORD res;
2936
2937     res = pSRRemoveRestorePoint(seq_number);
2938     if (res != ERROR_SUCCESS)
2939         trace("Failed to remove the restore point : %08x\n", res);
2940 }
2941
2942 static void test_MsiInstallProduct(void)
2943 {
2944     UINT r;
2945     CHAR path[MAX_PATH];
2946     LONG res;
2947     HKEY hkey;
2948     DWORD num, size, type;
2949
2950     if (on_win9x)
2951     {
2952         win_skip("Services are not implemented on Win9x and WinMe\n");
2953         return;
2954     }
2955
2956     /* szPackagePath is NULL */
2957     r = MsiInstallProductA(NULL, "INSTALL=ALL");
2958     ok(r == ERROR_INVALID_PARAMETER,
2959        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2960
2961     /* both szPackagePath and szCommandLine are NULL */
2962     r = MsiInstallProductA(NULL, NULL);
2963     ok(r == ERROR_INVALID_PARAMETER,
2964        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2965
2966     /* szPackagePath is empty */
2967     r = MsiInstallProductA("", "INSTALL=ALL");
2968     ok(r == ERROR_PATH_NOT_FOUND,
2969        "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
2970
2971     create_test_files();
2972     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
2973
2974     /* install, don't publish */
2975     r = MsiInstallProductA(msifile, NULL);
2976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2977
2978     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2979     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2980     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2981     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2982     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2983     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2984     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2985     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2986     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2987     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2988     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2989     ok(delete_pf("msitest", FALSE), "File not installed\n");
2990
2991     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2993
2994     size = MAX_PATH;
2995     type = REG_SZ;
2996     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
2997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2998     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
2999
3000     size = MAX_PATH;
3001     type = REG_SZ;
3002     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
3003     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3004
3005     size = sizeof(num);
3006     type = REG_DWORD;
3007     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
3008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3009     ok(num == 314, "Expected 314, got %d\n", num);
3010
3011     size = MAX_PATH;
3012     type = REG_SZ;
3013     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
3014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3015     ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
3016
3017     check_service_is_installed();
3018
3019     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3020
3021     /* not published, reinstall */
3022     r = MsiInstallProductA(msifile, NULL);
3023     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3024
3025     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3026     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3027     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3028     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3029     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3030     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3031     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3032     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3033     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3034     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3035     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3036     ok(delete_pf("msitest", FALSE), "File not installed\n");
3037
3038     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3040     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3041
3042     create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table));
3043
3044     /* not published, RemovePreviousVersions set */
3045     r = MsiInstallProductA(msifile, NULL);
3046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3047
3048     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3049     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3050     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3051     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3052     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3053     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3054     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3055     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3056     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3057     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3058     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3059     ok(delete_pf("msitest", FALSE), "File not installed\n");
3060
3061     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3062     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3063     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3064
3065     create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table));
3066
3067     /* not published, version number bumped */
3068     r = MsiInstallProductA(msifile, NULL);
3069     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3070
3071     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3072     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3073     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3074     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3075     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3076     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3077     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3078     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3079     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3080     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3081     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3082     ok(delete_pf("msitest", FALSE), "File not installed\n");
3083
3084     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3086     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3087
3088     create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table));
3089
3090     /* not published, RemovePreviousVersions set and version number bumped */
3091     r = MsiInstallProductA(msifile, NULL);
3092     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3093
3094     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3095     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3096     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3097     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3098     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3099     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3100     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3101     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3102     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3103     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3104     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3105     ok(delete_pf("msitest", FALSE), "File not installed\n");
3106
3107     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3109     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3110
3111     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3112
3113     /* install, publish product */
3114     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3115     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3116
3117     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3118     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3119     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3120     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3121     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3122     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3123     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3124     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3125     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3126     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3127     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3128     ok(delete_pf("msitest", FALSE), "File not installed\n");
3129
3130     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3131     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3132
3133     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3134
3135     /* published, reinstall */
3136     r = MsiInstallProductA(msifile, NULL);
3137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3138
3139     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3140     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3141     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3142     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3143     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3144     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3145     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3146     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3147     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3148     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3149     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3150     ok(delete_pf("msitest", FALSE), "File not installed\n");
3151
3152     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3153     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3154
3155     create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table));
3156
3157     /* published product, RemovePreviousVersions set */
3158     r = MsiInstallProductA(msifile, NULL);
3159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3160
3161     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3162     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3163     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3164     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3165     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3166     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3167     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3168     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3169     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3170     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3171     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3172     ok(delete_pf("msitest", FALSE), "File not installed\n");
3173
3174     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3175     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3176
3177     create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table));
3178
3179     /* published product, version number bumped */
3180     r = MsiInstallProductA(msifile, NULL);
3181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3182
3183     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3184     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3185     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3186     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3187     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3188     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3189     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3190     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3191     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3192     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3193     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3194     ok(delete_pf("msitest", FALSE), "File not installed\n");
3195
3196     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3197     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3198
3199     create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table));
3200
3201     /* published product, RemovePreviousVersions set and version number bumped */
3202     r = MsiInstallProductA(msifile, NULL);
3203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3204
3205     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3206     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3207     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3208     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3209     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3210     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3211     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3212     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3213     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3214     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3215     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3216     ok(delete_pf("msitest", FALSE), "File not installed\n");
3217
3218     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3219     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3220
3221     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3223
3224     delete_test_files();
3225 }
3226
3227 static void test_MsiSetComponentState(void)
3228 {
3229     INSTALLSTATE installed, action;
3230     MSIHANDLE package;
3231     char path[MAX_PATH];
3232     UINT r;
3233
3234     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3235
3236     CoInitialize(NULL);
3237
3238     lstrcpy(path, CURR_DIR);
3239     lstrcat(path, "\\");
3240     lstrcat(path, msifile);
3241
3242     r = MsiOpenPackage(path, &package);
3243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3244
3245     r = MsiDoAction(package, "CostInitialize");
3246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3247
3248     r = MsiDoAction(package, "FileCost");
3249     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3250
3251     r = MsiDoAction(package, "CostFinalize");
3252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3253
3254     r = MsiGetComponentState(package, "dangler", &installed, &action);
3255     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3256     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
3257     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
3258
3259     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
3260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3261
3262     MsiCloseHandle(package);
3263     CoUninitialize();
3264
3265     DeleteFileA(msifile);
3266 }
3267
3268 static void test_packagecoltypes(void)
3269 {
3270     MSIHANDLE hdb, view, rec;
3271     char path[MAX_PATH];
3272     LPCSTR query;
3273     UINT r, count;
3274
3275     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3276
3277     CoInitialize(NULL);
3278
3279     lstrcpy(path, CURR_DIR);
3280     lstrcat(path, "\\");
3281     lstrcat(path, msifile);
3282
3283     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
3284     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3285
3286     query = "SELECT * FROM `Media`";
3287     r = MsiDatabaseOpenView( hdb, query, &view );
3288     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3289
3290     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
3291     count = MsiRecordGetFieldCount( rec );
3292     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3293     ok(count == 6, "Expected 6, got %d\n", count);
3294     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
3295     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
3296     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
3297     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
3298     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
3299     ok(check_record(rec, 6, "Source"), "wrong column label\n");
3300     MsiCloseHandle(rec);
3301
3302     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
3303     count = MsiRecordGetFieldCount( rec );
3304     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3305     ok(count == 6, "Expected 6, got %d\n", count);
3306     ok(check_record(rec, 1, "i2"), "wrong column label\n");
3307     ok(check_record(rec, 2, "i4"), "wrong column label\n");
3308     ok(check_record(rec, 3, "L64"), "wrong column label\n");
3309     ok(check_record(rec, 4, "S255"), "wrong column label\n");
3310     ok(check_record(rec, 5, "S32"), "wrong column label\n");
3311     ok(check_record(rec, 6, "S72"), "wrong column label\n");
3312
3313     MsiCloseHandle(rec);
3314     MsiCloseHandle(view);
3315     MsiCloseHandle(hdb);
3316     CoUninitialize();
3317
3318     DeleteFile(msifile);
3319 }
3320
3321 static void create_cc_test_files(void)
3322 {
3323     CCAB cabParams;
3324     HFCI hfci;
3325     ERF erf;
3326     static CHAR cab_context[] = "test%d.cab";
3327     BOOL res;
3328
3329     create_file("maximus", 500);
3330     create_file("augustus", 50000);
3331     create_file("tiberius", 500);
3332     create_file("caesar", 500);
3333
3334     set_cab_parameters(&cabParams, "test1.cab", 40000);
3335
3336     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
3337                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
3338                       get_temp_file, &cabParams, cab_context);
3339     ok(hfci != NULL, "Failed to create an FCI context\n");
3340
3341     res = add_file(hfci, "maximus", tcompTYPE_NONE);
3342     ok(res, "Failed to add file maximus\n");
3343
3344     res = add_file(hfci, "augustus", tcompTYPE_NONE);
3345     ok(res, "Failed to add file augustus\n");
3346
3347     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
3348     ok(res, "Failed to add file tiberius\n");
3349
3350     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
3351     ok(res, "Failed to flush the cabinet\n");
3352
3353     res = FCIDestroy(hfci);
3354     ok(res, "Failed to destroy the cabinet\n");
3355
3356     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3357
3358     DeleteFile("maximus");
3359     DeleteFile("augustus");
3360     DeleteFile("tiberius");
3361     DeleteFile("caesar");
3362 }
3363
3364 static void delete_cab_files(void)
3365 {
3366     SHFILEOPSTRUCT shfl;
3367     CHAR path[MAX_PATH+10];
3368
3369     lstrcpyA(path, CURR_DIR);
3370     lstrcatA(path, "\\*.cab");
3371     path[strlen(path) + 1] = '\0';
3372
3373     shfl.hwnd = NULL;
3374     shfl.wFunc = FO_DELETE;
3375     shfl.pFrom = path;
3376     shfl.pTo = NULL;
3377     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
3378
3379     SHFileOperation(&shfl);
3380 }
3381
3382 static void test_continuouscabs(void)
3383 {
3384     UINT r;
3385
3386     create_cc_test_files();
3387     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3388
3389     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3390
3391     r = MsiInstallProductA(msifile, NULL);
3392     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3393     {
3394         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3395         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3396         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3397         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3398         ok(delete_pf("msitest", FALSE), "File not installed\n");
3399     }
3400
3401     delete_cab_files();
3402     DeleteFile(msifile);
3403
3404     create_cc_test_files();
3405     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
3406
3407     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3408
3409     r = MsiInstallProductA(msifile, NULL);
3410     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3411     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3412     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3413     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
3414     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3415     ok(delete_pf("msitest", FALSE), "File not installed\n");
3416
3417     delete_cab_files();
3418     DeleteFile(msifile);
3419 }
3420
3421 static void test_caborder(void)
3422 {
3423     UINT r;
3424
3425     create_file("imperator", 100);
3426     create_file("maximus", 500);
3427     create_file("augustus", 50000);
3428     create_file("caesar", 500);
3429
3430     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3431
3432     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3433
3434     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3435     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3436     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3437
3438     r = MsiInstallProductA(msifile, NULL);
3439     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3440     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3441     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3442     todo_wine
3443     {
3444         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3445         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3446     }
3447
3448     delete_cab_files();
3449
3450     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
3451     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
3452     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3453
3454     r = MsiInstallProductA(msifile, NULL);
3455     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3456     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3457     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3458     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3459     todo_wine
3460     {
3461         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3462     }
3463
3464     delete_cab_files();
3465     DeleteFile(msifile);
3466
3467     create_cc_test_files();
3468     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
3469
3470     r = MsiInstallProductA(msifile, NULL);
3471     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3472     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3473     ok(!delete_pf("msitest", FALSE), "File is installed\n");
3474     todo_wine
3475     {
3476         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3477         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3478     }
3479
3480     delete_cab_files();
3481     DeleteFile(msifile);
3482
3483     create_cc_test_files();
3484     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
3485
3486     r = MsiInstallProductA(msifile, NULL);
3487     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3488     todo_wine
3489     {
3490         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3491         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3492         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3493         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3494     }
3495
3496     delete_cab_files();
3497     DeleteFile("imperator");
3498     DeleteFile("maximus");
3499     DeleteFile("augustus");
3500     DeleteFile("caesar");
3501     DeleteFile(msifile);
3502 }
3503
3504 static void test_mixedmedia(void)
3505 {
3506     UINT r;
3507
3508     CreateDirectoryA("msitest", NULL);
3509     create_file("msitest\\maximus", 500);
3510     create_file("msitest\\augustus", 500);
3511     create_file("caesar", 500);
3512
3513     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
3514
3515     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3516
3517     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
3518
3519     r = MsiInstallProductA(msifile, NULL);
3520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3521     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3522     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3523     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3524     ok(delete_pf("msitest", FALSE), "File not installed\n");
3525
3526     /* Delete the files in the temp (current) folder */
3527     DeleteFile("msitest\\maximus");
3528     DeleteFile("msitest\\augustus");
3529     RemoveDirectory("msitest");
3530     DeleteFile("caesar");
3531     DeleteFile("test1.cab");
3532     DeleteFile(msifile);
3533 }
3534
3535 static void test_samesequence(void)
3536 {
3537     UINT r;
3538
3539     create_cc_test_files();
3540     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
3541
3542     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3543
3544     r = MsiInstallProductA(msifile, NULL);
3545     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3546     {
3547         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3548         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3549         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3550         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3551         ok(delete_pf("msitest", FALSE), "File not installed\n");
3552     }
3553
3554     delete_cab_files();
3555     DeleteFile(msifile);
3556 }
3557
3558 static void test_uiLevelFlags(void)
3559 {
3560     UINT r;
3561
3562     create_cc_test_files();
3563     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
3564
3565     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
3566
3567     r = MsiInstallProductA(msifile, NULL);
3568     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3569     {
3570         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3571         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
3572         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3573         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3574         ok(delete_pf("msitest", FALSE), "File not installed\n");
3575     }
3576
3577     delete_cab_files();
3578     DeleteFile(msifile);
3579 }
3580
3581 static BOOL file_matches(LPSTR path)
3582 {
3583     CHAR buf[MAX_PATH];
3584     HANDLE file;
3585     DWORD size;
3586
3587     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3588                       NULL, OPEN_EXISTING, 0, NULL);
3589
3590     ZeroMemory(buf, MAX_PATH);
3591     ReadFile(file, buf, 15, &size, NULL);
3592     CloseHandle(file);
3593
3594     return !lstrcmp(buf, "msitest\\maximus");
3595 }
3596
3597 static void test_readonlyfile(void)
3598 {
3599     UINT r;
3600     DWORD size;
3601     HANDLE file;
3602     CHAR path[MAX_PATH];
3603
3604     CreateDirectoryA("msitest", NULL);
3605     create_file("msitest\\maximus", 500);
3606     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
3607
3608     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3609
3610     lstrcpy(path, PROG_FILES_DIR);
3611     lstrcat(path, "\\msitest");
3612     CreateDirectory(path, NULL);
3613
3614     lstrcat(path, "\\maximus");
3615     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3616                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3617
3618     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3619     CloseHandle(file);
3620
3621     r = MsiInstallProductA(msifile, NULL);
3622     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3623     ok(file_matches(path), "Expected file to be overwritten\n");
3624     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3625     ok(delete_pf("msitest", FALSE), "File not installed\n");
3626
3627     /* Delete the files in the temp (current) folder */
3628     DeleteFile("msitest\\maximus");
3629     RemoveDirectory("msitest");
3630     DeleteFile(msifile);
3631 }
3632
3633 static void test_readonlyfile_cab(void)
3634 {
3635     UINT r;
3636     DWORD size;
3637     HANDLE file;
3638     CHAR path[MAX_PATH];
3639     CHAR buf[16];
3640
3641     CreateDirectoryA("msitest", NULL);
3642     create_file("maximus", 500);
3643     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3644     DeleteFile("maximus");
3645
3646     create_database(msifile, rofc_tables, sizeof(rofc_tables) / sizeof(msi_table));
3647
3648     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3649
3650     lstrcpy(path, PROG_FILES_DIR);
3651     lstrcat(path, "\\msitest");
3652     CreateDirectory(path, NULL);
3653
3654     lstrcat(path, "\\maximus");
3655     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3656                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3657
3658     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3659     CloseHandle(file);
3660
3661     r = MsiInstallProductA(msifile, NULL);
3662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3663
3664     memset( buf, 0, sizeof(buf) );
3665     if ((file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3666                            NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
3667     {
3668         ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
3669         CloseHandle(file);
3670     }
3671     ok(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "Expected file to be overwritten, got '%s'\n", buf);
3672     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3673     ok(delete_pf("msitest", FALSE), "File not installed\n");
3674
3675     /* Delete the files in the temp (current) folder */
3676     delete_cab_files();
3677     DeleteFile("msitest\\maximus");
3678     RemoveDirectory("msitest");
3679     DeleteFile(msifile);
3680 }
3681
3682 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
3683 {
3684     WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
3685     IStorage *stg;
3686     IStream *stm;
3687     HRESULT hr;
3688     HANDLE handle;
3689
3690     MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
3691     hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
3692     if (FAILED(hr))
3693         return FALSE;
3694
3695     MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
3696     hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3697     if (FAILED(hr))
3698     {
3699         IStorage_Release(stg);
3700         return FALSE;
3701     }
3702
3703     handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
3704     if (handle != INVALID_HANDLE_VALUE)
3705     {
3706         DWORD count;
3707         char buffer[1024];
3708         if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
3709             IStream_Write(stm, buffer, count, &count);
3710         CloseHandle(handle);
3711     }
3712
3713     IStream_Release(stm);
3714     IStorage_Release(stg);
3715
3716     return TRUE;
3717 }
3718
3719 static void test_lastusedsource(void)
3720 {
3721     static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3722
3723     UINT r;
3724     char value[MAX_PATH], path[MAX_PATH];
3725     DWORD size;
3726
3727     if (!pMsiSourceListGetInfoA)
3728     {
3729         win_skip("MsiSourceListGetInfoA is not available\n");
3730         return;
3731     }
3732
3733     CreateDirectoryA("msitest", NULL);
3734     create_file("maximus", 500);
3735     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3736     DeleteFile("maximus");
3737
3738     create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
3739     create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
3740     create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
3741
3742     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3743
3744     /* no cabinet file */
3745
3746     size = MAX_PATH;
3747     lstrcpyA(value, "aaa");
3748     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3749                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3750     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3751     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3752
3753     r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
3754     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3755
3756     lstrcpyA(path, CURR_DIR);
3757     lstrcatA(path, "\\");
3758
3759     size = MAX_PATH;
3760     lstrcpyA(value, "aaa");
3761     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3762                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3763     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3764     todo_wine
3765     {
3766     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3767     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3768     }
3769
3770     r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
3771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3772
3773     /* separate cabinet file */
3774
3775     size = MAX_PATH;
3776     lstrcpyA(value, "aaa");
3777     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3778                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3779     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3780     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3781
3782     r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
3783     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3784
3785     lstrcpyA(path, CURR_DIR);
3786     lstrcatA(path, "\\");
3787
3788     size = MAX_PATH;
3789     lstrcpyA(value, "aaa");
3790     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3791                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3793     todo_wine
3794     {
3795     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3796     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3797     }
3798
3799     r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
3800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3801
3802     size = MAX_PATH;
3803     lstrcpyA(value, "aaa");
3804     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3805                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3806     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3807     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3808
3809     /* embedded cabinet stream */
3810
3811     add_cabinet_storage("msifile2.msi", "test1.cab");
3812
3813     r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
3814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3815
3816     size = MAX_PATH;
3817     lstrcpyA(value, "aaa");
3818     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3819                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3821     todo_wine
3822     {
3823     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3824     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3825     }
3826
3827     r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
3828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3829
3830     size = MAX_PATH;
3831     lstrcpyA(value, "aaa");
3832     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3833                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3834     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3835     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3836
3837     /* Delete the files in the temp (current) folder */
3838     delete_cab_files();
3839     DeleteFile("msitest\\maximus");
3840     RemoveDirectory("msitest");
3841     DeleteFile("msifile0.msi");
3842     DeleteFile("msifile1.msi");
3843     DeleteFile("msifile2.msi");
3844 }
3845
3846 static void test_setdirproperty(void)
3847 {
3848     UINT r;
3849
3850     CreateDirectoryA("msitest", NULL);
3851     create_file("msitest\\maximus", 500);
3852     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
3853
3854     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3855
3856     r = MsiInstallProductA(msifile, NULL);
3857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3858     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
3859     ok(delete_cf("msitest", FALSE), "File not installed\n");
3860
3861     /* Delete the files in the temp (current) folder */
3862     DeleteFile(msifile);
3863     DeleteFile("msitest\\maximus");
3864     RemoveDirectory("msitest");
3865 }
3866
3867 static void test_cabisextracted(void)
3868 {
3869     UINT r;
3870
3871     CreateDirectoryA("msitest", NULL);
3872     create_file("msitest\\gaius", 500);
3873     create_file("maximus", 500);
3874     create_file("augustus", 500);
3875     create_file("caesar", 500);
3876
3877     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3878     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3879     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3880
3881     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
3882
3883     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3884
3885     r = MsiInstallProductA(msifile, NULL);
3886     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3887     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3888     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3889     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3890     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
3891     ok(delete_pf("msitest", FALSE), "File not installed\n");
3892
3893     /* Delete the files in the temp (current) folder */
3894     delete_cab_files();
3895     DeleteFile(msifile);
3896     DeleteFile("maximus");
3897     DeleteFile("augustus");
3898     DeleteFile("caesar");
3899     DeleteFile("msitest\\gaius");
3900     RemoveDirectory("msitest");
3901 }
3902
3903 static void test_concurrentinstall(void)
3904 {
3905     UINT r;
3906     CHAR path[MAX_PATH];
3907
3908     CreateDirectoryA("msitest", NULL);
3909     CreateDirectoryA("msitest\\msitest", NULL);
3910     create_file("msitest\\maximus", 500);
3911     create_file("msitest\\msitest\\augustus", 500);
3912
3913     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
3914
3915     lstrcpyA(path, CURR_DIR);
3916     lstrcatA(path, "\\msitest\\concurrent.msi");
3917     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
3918
3919     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3920
3921     r = MsiInstallProductA(msifile, NULL);
3922     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3923     if (!delete_pf("msitest\\augustus", TRUE))
3924         trace("concurrent installs not supported\n");
3925     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3926     ok(delete_pf("msitest", FALSE), "File not installed\n");
3927
3928     DeleteFile(path);
3929
3930     r = MsiInstallProductA(msifile, NULL);
3931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3932     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3933     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3934     ok(delete_pf("msitest", FALSE), "File not installed\n");
3935
3936     DeleteFile(msifile);
3937     DeleteFile("msitest\\msitest\\augustus");
3938     DeleteFile("msitest\\maximus");
3939     RemoveDirectory("msitest\\msitest");
3940     RemoveDirectory("msitest");
3941 }
3942
3943 static void test_setpropertyfolder(void)
3944 {
3945     UINT r;
3946     CHAR path[MAX_PATH];
3947     DWORD attr;
3948
3949     lstrcpyA(path, PROG_FILES_DIR);
3950     lstrcatA(path, "\\msitest\\added");
3951
3952     CreateDirectoryA("msitest", NULL);
3953     create_file("msitest\\maximus", 500);
3954
3955     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
3956
3957     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3958
3959     r = MsiInstallProductA(msifile, NULL);
3960     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3961     attr = GetFileAttributesA(path);
3962     if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
3963     {
3964         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
3965         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
3966         ok(delete_pf("msitest", FALSE), "File not installed\n");
3967     }
3968     else
3969     {
3970         trace("changing folder property not supported\n");
3971         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3972         ok(delete_pf("msitest", FALSE), "File not installed\n");
3973     }
3974
3975     /* Delete the files in the temp (current) folder */
3976     DeleteFile(msifile);
3977     DeleteFile("msitest\\maximus");
3978     RemoveDirectory("msitest");
3979 }
3980
3981 static BOOL file_exists(LPCSTR file)
3982 {
3983     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
3984 }
3985
3986 static BOOL pf_exists(LPCSTR file)
3987 {
3988     CHAR path[MAX_PATH];
3989
3990     lstrcpyA(path, PROG_FILES_DIR);
3991     lstrcatA(path, "\\");
3992     lstrcatA(path, file);
3993
3994     return file_exists(path);
3995 }
3996
3997 static void delete_pfmsitest_files(void)
3998 {
3999     SHFILEOPSTRUCT shfl;
4000     CHAR path[MAX_PATH+11];
4001
4002     lstrcpyA(path, PROG_FILES_DIR);
4003     lstrcatA(path, "\\msitest\\*");
4004     path[strlen(path) + 1] = '\0';
4005
4006     shfl.hwnd = NULL;
4007     shfl.wFunc = FO_DELETE;
4008     shfl.pFrom = path;
4009     shfl.pTo = NULL;
4010     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
4011
4012     SHFileOperation(&shfl);
4013
4014     lstrcpyA(path, PROG_FILES_DIR);
4015     lstrcatA(path, "\\msitest");
4016     RemoveDirectoryA(path);
4017 }
4018
4019 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
4020 {
4021     char val[MAX_PATH];
4022     DWORD size, type;
4023     LONG res;
4024
4025     size = MAX_PATH;
4026     val[0] = '\0';
4027     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
4028
4029     if (res != ERROR_SUCCESS ||
4030         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
4031     {
4032         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4033         return;
4034     }
4035
4036     if (!expected)
4037         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
4038     else
4039     {
4040         if (bcase)
4041             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
4042         else
4043             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
4044     }
4045 }
4046
4047 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
4048 {
4049     DWORD val, size, type;
4050     LONG res;
4051
4052     size = sizeof(DWORD);
4053     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4054
4055     if (res != ERROR_SUCCESS || type != REG_DWORD)
4056     {
4057         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4058         return;
4059     }
4060
4061     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
4062 }
4063
4064 static void check_reg_dword2(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD line)
4065 {
4066     DWORD val, size, type;
4067     LONG res;
4068
4069     size = sizeof(DWORD);
4070     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4071
4072     if (res != ERROR_SUCCESS || type != REG_DWORD)
4073     {
4074         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4075         return;
4076     }
4077
4078     ok_(__FILE__, line)(val == expected1 || val == expected2, "Expected %d or %d, got %d\n", expected1, expected2, val);
4079 }
4080
4081 static void check_reg_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line)
4082 {
4083     DWORD val, size, type;
4084     LONG res;
4085
4086     size = sizeof(DWORD);
4087     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4088
4089     if (res != ERROR_SUCCESS || type != REG_DWORD)
4090     {
4091         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4092         return;
4093     }
4094
4095     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3,
4096                         "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val);
4097 }
4098
4099 #define CHECK_REG_STR(prodkey, name, expected) \
4100     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
4101
4102 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
4103     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
4104     RegDeleteValueA(prodkey, name);
4105
4106 #define CHECK_REG_ISTR(prodkey, name, expected) \
4107     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
4108
4109 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
4110     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
4111     RegDeleteValueA(prodkey, name);
4112
4113 #define CHECK_REG_DWORD(prodkey, name, expected) \
4114     check_reg_dword(prodkey, name, expected, __LINE__);
4115
4116 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
4117     check_reg_dword(prodkey, name, expected, __LINE__); \
4118     RegDeleteValueA(prodkey, name);
4119
4120 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
4121     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
4122
4123 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
4124     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
4125     RegDeleteValueA(prodkey, name);
4126
4127 #define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4128     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__);
4129
4130 #define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4131     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \
4132     RegDeleteValueA(prodkey, name);
4133
4134 static void get_date_str(LPSTR date)
4135 {
4136     SYSTEMTIME systime;
4137
4138     static const char date_fmt[] = "%d%02d%02d";
4139     GetLocalTime(&systime);
4140     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
4141 }
4142
4143 static void test_publish_registerproduct(void)
4144 {
4145     UINT r;
4146     LONG res;
4147     HKEY hkey;
4148     HKEY props, usage;
4149     LPSTR usersid;
4150     char date[MAX_PATH];
4151     char temp[MAX_PATH];
4152     char keypath[MAX_PATH];
4153
4154     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4155                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4156     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4157                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4158     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4159                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4160     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4161                                     "\\51AAE0C44620A5E4788506E91F249BD2";
4162
4163     if (!get_user_sid(&usersid))
4164         return;
4165
4166     get_date_str(date);
4167     GetTempPath(MAX_PATH, temp);
4168
4169     CreateDirectoryA("msitest", NULL);
4170     create_file("msitest\\maximus", 500);
4171
4172     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4173
4174     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4175
4176     /* RegisterProduct */
4177     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4178     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4179     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4180     ok(delete_pf("msitest", FALSE), "File not installed\n");
4181
4182     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
4183     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4184
4185     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4187
4188     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4189     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4190     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4191     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4192     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4193     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4194     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4195     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4196     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4197     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4198     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4199     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4200     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4201     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4202     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4203     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4204     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4205     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4206     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4207     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4208     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4209     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4210     todo_wine
4211     {
4212         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4213     }
4214
4215     RegDeleteKeyA(hkey, "");
4216     RegCloseKey(hkey);
4217
4218     sprintf(keypath, userdata, usersid);
4219     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4221
4222     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4224
4225     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4226     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4227     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4228     CHECK_DEL_REG_STR(props, "InstallDate", date);
4229     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4230     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4231     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4232     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4233     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4234     CHECK_DEL_REG_STR(props, "Comments", NULL);
4235     CHECK_DEL_REG_STR(props, "Contact", NULL);
4236     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4237     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4238     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4239     CHECK_DEL_REG_STR(props, "Readme", NULL);
4240     CHECK_DEL_REG_STR(props, "Size", NULL);
4241     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4242     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4243     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4244     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4245     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4246     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4247     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4248     todo_wine
4249     {
4250         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4251     }
4252
4253     RegDeleteKeyA(props, "");
4254     RegCloseKey(props);
4255
4256     res = RegOpenKeyA(hkey, "Usage", &usage);
4257     todo_wine
4258     {
4259         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4260     }
4261
4262     RegDeleteKeyA(usage, "");
4263     RegCloseKey(usage);
4264     RegDeleteKeyA(hkey, "");
4265     RegCloseKey(hkey);
4266
4267     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4269
4270     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4271
4272     RegDeleteKeyA(hkey, "");
4273     RegCloseKey(hkey);
4274
4275     /* RegisterProduct, machine */
4276     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
4277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4278     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4279     ok(delete_pf("msitest", FALSE), "File not installed\n");
4280
4281     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
4282     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4283
4284     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4286
4287     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4288     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4289     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4290     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4291     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4292     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4293     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4294     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4295     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4296     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4297     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4298     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4299     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4300     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4301     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4302     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4303     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4304     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4305     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4306     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4307     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4308     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4309     todo_wine
4310     {
4311         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4312     }
4313
4314     RegDeleteKeyA(hkey, "");
4315     RegCloseKey(hkey);
4316
4317     sprintf(keypath, userdata, "S-1-5-18");
4318     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4320
4321     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4322     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4323
4324     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4325     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4326     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4327     CHECK_DEL_REG_STR(props, "InstallDate", date);
4328     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4329     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4330     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4331     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4332     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4333     CHECK_DEL_REG_STR(props, "Comments", NULL);
4334     CHECK_DEL_REG_STR(props, "Contact", NULL);
4335     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4336     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4337     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4338     CHECK_DEL_REG_STR(props, "Readme", NULL);
4339     CHECK_DEL_REG_STR(props, "Size", NULL);
4340     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4341     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4342     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4343     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4344     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4345     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4346     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4347     todo_wine
4348     {
4349         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4350     }
4351
4352     RegDeleteKeyA(props, "");
4353     RegCloseKey(props);
4354
4355     res = RegOpenKeyA(hkey, "Usage", &usage);
4356     todo_wine
4357     {
4358         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4359     }
4360
4361     RegDeleteKeyA(usage, "");
4362     RegCloseKey(usage);
4363     RegDeleteKeyA(hkey, "");
4364     RegCloseKey(hkey);
4365
4366     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4368
4369     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4370
4371     RegDeleteKeyA(hkey, "");
4372     RegCloseKey(hkey);
4373
4374     DeleteFile(msifile);
4375     DeleteFile("msitest\\maximus");
4376     RemoveDirectory("msitest");
4377     HeapFree(GetProcessHeap(), 0, usersid);
4378 }
4379
4380 static void test_publish_publishproduct(void)
4381 {
4382     UINT r;
4383     LONG res;
4384     LPSTR usersid;
4385     HKEY sourcelist, net, props;
4386     HKEY hkey, patches, media;
4387     CHAR keypath[MAX_PATH];
4388     CHAR temp[MAX_PATH];
4389     CHAR path[MAX_PATH];
4390
4391     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4392                                    "\\Installer\\UserData\\%s\\Products"
4393                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4394     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
4395                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4396     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4397                                      "\\51AAE0C44620A5E4788506E91F249BD2";
4398     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4399                                   "\\Installer\\Products"
4400                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4401     static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4402     static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4403
4404     if (!get_user_sid(&usersid))
4405         return;
4406
4407     GetTempPath(MAX_PATH, temp);
4408
4409     CreateDirectoryA("msitest", NULL);
4410     create_file("msitest\\maximus", 500);
4411
4412     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4413
4414     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4415
4416     /* PublishProduct, current user */
4417     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4418     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4419     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4420     ok(delete_pf("msitest", FALSE), "File not installed\n");
4421
4422     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4423     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4424
4425     sprintf(keypath, prodpath, usersid);
4426     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4428
4429     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4430     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4431
4432     res = RegOpenKeyA(hkey, "Patches", &patches);
4433     todo_wine
4434     {
4435         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4436
4437         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4438     }
4439
4440     RegDeleteKeyA(patches, "");
4441     RegCloseKey(patches);
4442     RegDeleteKeyA(hkey, "");
4443     RegCloseKey(hkey);
4444
4445     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4447
4448     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4449     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4450     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4451     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4452     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4453     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
4454     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4455     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4456     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4457
4458     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
4459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4460
4461     lstrcpyA(path, "n;1;");
4462     lstrcatA(path, temp);
4463     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
4464     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
4465
4466     res = RegOpenKeyA(sourcelist, "Net", &net);
4467     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4468
4469     CHECK_DEL_REG_STR(net, "1", temp);
4470
4471     RegDeleteKeyA(net, "");
4472     RegCloseKey(net);
4473
4474     res = RegOpenKeyA(sourcelist, "Media", &media);
4475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4476
4477     CHECK_DEL_REG_STR(media, "1", "DISK1;");
4478
4479     RegDeleteKeyA(media, "");
4480     RegCloseKey(media);
4481     RegDeleteKeyA(sourcelist, "");
4482     RegCloseKey(sourcelist);
4483     RegDeleteKeyA(hkey, "");
4484     RegCloseKey(hkey);
4485
4486     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
4487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4488
4489     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4490
4491     RegDeleteKeyA(hkey, "");
4492     RegCloseKey(hkey);
4493
4494     /* PublishProduct, machine */
4495     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
4496     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4497     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4498     ok(delete_pf("msitest", FALSE), "File not installed\n");
4499
4500     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4501     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4502
4503     sprintf(keypath, prodpath, "S-1-5-18");
4504     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4505     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4506
4507     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4508     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4509
4510     res = RegOpenKeyA(hkey, "Patches", &patches);
4511     todo_wine
4512     {
4513         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4514
4515         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4516     }
4517
4518     RegDeleteKeyA(patches, "");
4519     RegCloseKey(patches);
4520     RegDeleteKeyA(hkey, "");
4521     RegCloseKey(hkey);
4522
4523     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
4524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4525
4526     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4527     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4528     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4529     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4530     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4531     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
4532     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4533     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4534     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4535
4536     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
4537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4538
4539     lstrcpyA(path, "n;1;");
4540     lstrcatA(path, temp);
4541     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
4542     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
4543
4544     res = RegOpenKeyA(sourcelist, "Net", &net);
4545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4546
4547     CHECK_DEL_REG_STR(net, "1", temp);
4548
4549     RegDeleteKeyA(net, "");
4550     RegCloseKey(net);
4551
4552     res = RegOpenKeyA(sourcelist, "Media", &media);
4553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4554
4555     CHECK_DEL_REG_STR(media, "1", "DISK1;");
4556
4557     RegDeleteKeyA(media, "");
4558     RegCloseKey(media);
4559     RegDeleteKeyA(sourcelist, "");
4560     RegCloseKey(sourcelist);
4561     RegDeleteKeyA(hkey, "");
4562     RegCloseKey(hkey);
4563
4564     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
4565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4566
4567     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4568
4569     RegDeleteKeyA(hkey, "");
4570     RegCloseKey(hkey);
4571
4572     DeleteFile(msifile);
4573     DeleteFile("msitest\\maximus");
4574     RemoveDirectory("msitest");
4575     HeapFree(GetProcessHeap(), 0, usersid);
4576 }
4577
4578 static void test_publish_publishfeatures(void)
4579 {
4580     UINT r;
4581     LONG res;
4582     HKEY hkey;
4583     LPSTR usersid;
4584     CHAR keypath[MAX_PATH];
4585
4586     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
4587                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4588     static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4589                                  "\\Installer\\UserData\\%s\\Products"
4590                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
4591     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4592                                   "\\Installer\\Features";
4593     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
4594                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4595
4596     if (!get_user_sid(&usersid))
4597         return;
4598
4599     CreateDirectoryA("msitest", NULL);
4600     create_file("msitest\\maximus", 500);
4601
4602     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4603
4604     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4605
4606     /* PublishFeatures, current user */
4607     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4609     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4610     ok(delete_pf("msitest", FALSE), "File not installed\n");
4611
4612     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
4613     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4614
4615     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
4616     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4617
4618     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
4619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4620
4621     CHECK_REG_STR(hkey, "feature", "");
4622     CHECK_REG_STR(hkey, "montecristo", "");
4623
4624     RegDeleteValueA(hkey, "feature");
4625     RegDeleteValueA(hkey, "montecristo");
4626     RegDeleteKeyA(hkey, "");
4627     RegCloseKey(hkey);
4628
4629     sprintf(keypath, udpath, usersid);
4630     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4631     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4632
4633     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
4634     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
4635
4636     RegDeleteValueA(hkey, "feature");
4637     RegDeleteValueA(hkey, "montecristo");
4638     RegDeleteKeyA(hkey, "");
4639     RegCloseKey(hkey);
4640
4641     /* PublishFeatures, machine */
4642     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
4643     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4644     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4645     ok(delete_pf("msitest", FALSE), "File not installed\n");
4646
4647     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
4648     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4649
4650     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
4651     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4652
4653     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
4654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4655
4656     CHECK_REG_STR(hkey, "feature", "");
4657     CHECK_REG_STR(hkey, "montecristo", "");
4658
4659     RegDeleteValueA(hkey, "feature");
4660     RegDeleteValueA(hkey, "montecristo");
4661     RegDeleteKeyA(hkey, "");
4662     RegCloseKey(hkey);
4663
4664     sprintf(keypath, udpath, "S-1-5-18");
4665     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4667
4668     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
4669     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
4670
4671     RegDeleteValueA(hkey, "feature");
4672     RegDeleteValueA(hkey, "montecristo");
4673     RegDeleteKeyA(hkey, "");
4674     RegCloseKey(hkey);
4675
4676     DeleteFile(msifile);
4677     DeleteFile("msitest\\maximus");
4678     RemoveDirectory("msitest");
4679     HeapFree(GetProcessHeap(), 0, usersid);
4680 }
4681
4682 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
4683 {
4684     DWORD len = 0;
4685     LPSTR val;
4686     LONG r;
4687
4688     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
4689     if (r != ERROR_SUCCESS)
4690         return NULL;
4691
4692     len += sizeof (WCHAR);
4693     val = HeapAlloc(GetProcessHeap(), 0, len);
4694     if (!val) return NULL;
4695     val[0] = 0;
4696     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
4697     return val;
4698 }
4699
4700 static void get_owner_company(LPSTR *owner, LPSTR *company)
4701 {
4702     LONG res;
4703     HKEY hkey;
4704
4705     *owner = *company = NULL;
4706
4707     res = RegOpenKeyA(HKEY_CURRENT_USER,
4708                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
4709     if (res == ERROR_SUCCESS)
4710     {
4711         *owner = reg_get_val_str(hkey, "DefName");
4712         *company = reg_get_val_str(hkey, "DefCompany");
4713         RegCloseKey(hkey);
4714     }
4715
4716     if (!*owner || !*company)
4717     {
4718         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
4719                           "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
4720         if (res == ERROR_SUCCESS)
4721         {
4722             *owner = reg_get_val_str(hkey, "RegisteredOwner");
4723             *company = reg_get_val_str(hkey, "RegisteredOrganization");
4724             RegCloseKey(hkey);
4725         }
4726     }
4727
4728     if (!*owner || !*company)
4729     {
4730         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
4731                           "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
4732         if (res == ERROR_SUCCESS)
4733         {
4734             *owner = reg_get_val_str(hkey, "RegisteredOwner");
4735             *company = reg_get_val_str(hkey, "RegisteredOrganization");
4736             RegCloseKey(hkey);
4737         }
4738     }
4739 }
4740
4741 static void test_publish_registeruser(void)
4742 {
4743     UINT r;
4744     LONG res;
4745     HKEY props;
4746     LPSTR usersid;
4747     LPSTR owner, company;
4748     CHAR keypath[MAX_PATH];
4749
4750     static const CHAR keyfmt[] =
4751         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
4752         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
4753
4754     if (!get_user_sid(&usersid))
4755         return;
4756
4757     get_owner_company(&owner, &company);
4758
4759     CreateDirectoryA("msitest", NULL);
4760     create_file("msitest\\maximus", 500);
4761
4762     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4763
4764     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4765
4766     /* RegisterUser, per-user */
4767     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
4768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4769     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4770     ok(delete_pf("msitest", FALSE), "File not installed\n");
4771
4772     sprintf(keypath, keyfmt, usersid);
4773
4774     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
4775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4776
4777     CHECK_REG_STR(props, "ProductID", "none");
4778     CHECK_REG_STR(props, "RegCompany", company);
4779     CHECK_REG_STR(props, "RegOwner", owner);
4780
4781     RegDeleteValueA(props, "ProductID");
4782     RegDeleteValueA(props, "RegCompany");
4783     RegDeleteValueA(props, "RegOwner");
4784     RegDeleteKeyA(props, "");
4785     RegCloseKey(props);
4786
4787     /* RegisterUser, machine */
4788     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
4789     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4790     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4791     ok(delete_pf("msitest", FALSE), "File not installed\n");
4792
4793     sprintf(keypath, keyfmt, "S-1-5-18");
4794
4795     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
4796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4797
4798     CHECK_REG_STR(props, "ProductID", "none");
4799     CHECK_REG_STR(props, "RegCompany", company);
4800     CHECK_REG_STR(props, "RegOwner", owner);
4801
4802     RegDeleteValueA(props, "ProductID");
4803     RegDeleteValueA(props, "RegCompany");
4804     RegDeleteValueA(props, "RegOwner");
4805     RegDeleteKeyA(props, "");
4806     RegCloseKey(props);
4807
4808     HeapFree(GetProcessHeap(), 0, company);
4809     HeapFree(GetProcessHeap(), 0, owner);
4810
4811     DeleteFile(msifile);
4812     DeleteFile("msitest\\maximus");
4813     RemoveDirectory("msitest");
4814     LocalFree(usersid);
4815 }
4816
4817 static void test_publish_processcomponents(void)
4818 {
4819     UINT r;
4820     LONG res;
4821     DWORD size;
4822     HKEY comp, hkey;
4823     LPSTR usersid;
4824     CHAR val[MAX_PATH];
4825     CHAR keypath[MAX_PATH];
4826     CHAR program_files_maximus[MAX_PATH];
4827
4828     static const CHAR keyfmt[] =
4829         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
4830         "UserData\\%s\\Components\\%s";
4831     static const CHAR compkey[] =
4832         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
4833
4834     if (!get_user_sid(&usersid))
4835         return;
4836
4837     CreateDirectoryA("msitest", NULL);
4838     create_file("msitest\\maximus", 500);
4839
4840     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
4841
4842     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4843
4844     /* ProcessComponents, per-user */
4845     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4846     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4847     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4848     ok(delete_pf("msitest", FALSE), "File not installed\n");
4849
4850     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
4851
4852     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4854
4855     size = MAX_PATH;
4856     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4857                            NULL, NULL, (LPBYTE)val, &size);
4858     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4859
4860     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
4861     lstrcatA(program_files_maximus,"\\msitest\\maximus");
4862
4863     ok(!lstrcmpiA(val, program_files_maximus),
4864        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
4865
4866     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4867     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4868
4869     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4870     RegDeleteKeyA(comp, "");
4871     RegCloseKey(comp);
4872
4873     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
4874
4875     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4877
4878     size = MAX_PATH;
4879     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4880                            NULL, NULL, (LPBYTE)val, &size);
4881     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4882     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
4883        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
4884
4885     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4886     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4887
4888     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4889     RegDeleteKeyA(comp, "");
4890     RegCloseKey(comp);
4891
4892     /* ProcessComponents, machine */
4893     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
4894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4895     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4896     ok(delete_pf("msitest", FALSE), "File not installed\n");
4897
4898     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
4899
4900     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4902
4903     size = MAX_PATH;
4904     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4905                            NULL, NULL, (LPBYTE)val, &size);
4906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4907     ok(!lstrcmpiA(val, program_files_maximus),
4908        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
4909
4910     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4911     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4912
4913     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4914     RegDeleteKeyA(comp, "");
4915     RegCloseKey(comp);
4916
4917     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
4918
4919     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4921
4922     size = MAX_PATH;
4923     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4924                            NULL, NULL, (LPBYTE)val, &size);
4925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4926     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
4927        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
4928
4929     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4930     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4931
4932     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4933     RegDeleteKeyA(comp, "");
4934     RegCloseKey(comp);
4935
4936     DeleteFile(msifile);
4937     DeleteFile("msitest\\maximus");
4938     RemoveDirectory("msitest");
4939     LocalFree(usersid);
4940 }
4941
4942 static void test_publish(void)
4943 {
4944     UINT r;
4945     LONG res;
4946     HKEY uninstall, prodkey;
4947     INSTALLSTATE state;
4948     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4949     char date[MAX_PATH];
4950     char temp[MAX_PATH];
4951
4952     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
4953
4954     if (!pMsiQueryComponentStateA)
4955     {
4956         win_skip("MsiQueryComponentStateA is not available\n");
4957         return;
4958     }
4959
4960     get_date_str(date);
4961     GetTempPath(MAX_PATH, temp);
4962
4963     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
4964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4965
4966     CreateDirectoryA("msitest", NULL);
4967     create_file("msitest\\maximus", 500);
4968
4969     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4970
4971     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4972
4973     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4974     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4975
4976     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4977     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4978
4979     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4980     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4981
4982     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4983                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4984     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4985     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4986
4987     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4988     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4989
4990     /* nothing published */
4991     r = MsiInstallProductA(msifile, NULL);
4992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4993     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4994     ok(pf_exists("msitest"), "File not installed\n");
4995
4996     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4997     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4998
4999     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5000     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5001
5002     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5003     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5004
5005     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5006                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5007     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5008     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5009
5010     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5011     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5012
5013     /* PublishProduct and RegisterProduct */
5014     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
5015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5016     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5017     ok(pf_exists("msitest"), "File not installed\n");
5018
5019     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5020     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5021
5022     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5023     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5024
5025     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5026     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5027
5028     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5029                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5030     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
5031     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5032
5033     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5035
5036     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5037     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5038     CHECK_REG_STR(prodkey, "InstallDate", date);
5039     CHECK_REG_STR(prodkey, "InstallSource", temp);
5040     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5041     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5042     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5043     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5044     CHECK_REG_STR(prodkey, "Comments", NULL);
5045     CHECK_REG_STR(prodkey, "Contact", NULL);
5046     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5047     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5048     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5049     CHECK_REG_STR(prodkey, "Readme", NULL);
5050     CHECK_REG_STR(prodkey, "Size", NULL);
5051     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5052     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5053     CHECK_REG_DWORD(prodkey, "Language", 1033);
5054     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5055     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5056     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5057     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5058     todo_wine
5059     {
5060         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5061     }
5062
5063     RegCloseKey(prodkey);
5064
5065     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5067     ok(pf_exists("msitest\\maximus"), "File deleted\n");
5068     ok(pf_exists("msitest"), "File deleted\n");
5069
5070     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5071     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5072
5073     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5074     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5075
5076     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5077     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5078
5079     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5080                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5081     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5082     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5083
5084     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5085     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5086
5087     /* complete install */
5088     r = MsiInstallProductA(msifile, "FULL=1");
5089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5090     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5091     ok(pf_exists("msitest"), "File not installed\n");
5092
5093     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5094     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5095
5096     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5097     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5098
5099     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5100     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5101
5102     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5103                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5104     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5105     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5106
5107     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5109
5110     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5111     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5112     CHECK_REG_STR(prodkey, "InstallDate", date);
5113     CHECK_REG_STR(prodkey, "InstallSource", temp);
5114     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5115     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5116     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5117     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5118     CHECK_REG_STR(prodkey, "Comments", NULL);
5119     CHECK_REG_STR(prodkey, "Contact", NULL);
5120     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5121     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5122     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5123     CHECK_REG_STR(prodkey, "Readme", NULL);
5124     CHECK_REG_STR(prodkey, "Size", NULL);
5125     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5126     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5127     CHECK_REG_DWORD(prodkey, "Language", 1033);
5128     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5129     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5130     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5131     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5132     todo_wine
5133     {
5134         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5135     }
5136
5137     RegCloseKey(prodkey);
5138
5139     /* no UnpublishFeatures */
5140     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5142     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5143     ok(!pf_exists("msitest"), "Directory not deleted\n");
5144
5145     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5146     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5147
5148     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5149     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5150
5151     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5152     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5153
5154     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5155                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5156     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5157     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5158
5159     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5160     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5161
5162     /* complete install */
5163     r = MsiInstallProductA(msifile, "FULL=1");
5164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5165     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5166     ok(pf_exists("msitest"), "File not installed\n");
5167
5168     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5169     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5170
5171     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5172     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5173
5174     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5175     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5176
5177     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5178                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5180     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5181
5182     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5184
5185     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5186     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5187     CHECK_REG_STR(prodkey, "InstallDate", date);
5188     CHECK_REG_STR(prodkey, "InstallSource", temp);
5189     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5190     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5191     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5192     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5193     CHECK_REG_STR(prodkey, "Comments", NULL);
5194     CHECK_REG_STR(prodkey, "Contact", NULL);
5195     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5196     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5197     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5198     CHECK_REG_STR(prodkey, "Readme", NULL);
5199     CHECK_REG_STR(prodkey, "Size", NULL);
5200     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5201     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5202     CHECK_REG_DWORD(prodkey, "Language", 1033);
5203     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5204     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5205     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5206     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5207     todo_wine
5208     {
5209         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5210     }
5211
5212     RegCloseKey(prodkey);
5213
5214     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
5215     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
5216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5217     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
5218     todo_wine ok(pf_exists("msitest"), "Directory deleted\n");
5219
5220     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5221     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5222
5223     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5224     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5225
5226     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5227     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5228
5229     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5230                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5232     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5233
5234     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5236
5237     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5238     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5239     CHECK_REG_STR(prodkey, "InstallDate", date);
5240     CHECK_REG_STR(prodkey, "InstallSource", temp);
5241     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5242     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5243     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5244     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5245     CHECK_REG_STR(prodkey, "Comments", NULL);
5246     CHECK_REG_STR(prodkey, "Contact", NULL);
5247     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5248     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5249     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5250     CHECK_REG_STR(prodkey, "Readme", NULL);
5251     CHECK_REG_STR(prodkey, "Size", NULL);
5252     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5253     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5254     CHECK_REG_DWORD(prodkey, "Language", 1033);
5255     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5256     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5257     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5258     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5259     todo_wine
5260     {
5261         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5262     }
5263
5264     RegCloseKey(prodkey);
5265
5266     /* complete install */
5267     r = MsiInstallProductA(msifile, "FULL=1");
5268     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5269     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5270     ok(pf_exists("msitest"), "File not installed\n");
5271
5272     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5273     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5274
5275     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5276     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5277
5278     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5279     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5280
5281     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5282                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5283     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5284     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5285
5286     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5288
5289     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5290     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5291     CHECK_REG_STR(prodkey, "InstallDate", date);
5292     CHECK_REG_STR(prodkey, "InstallSource", temp);
5293     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5294     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5295     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5296     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5297     CHECK_REG_STR(prodkey, "Comments", NULL);
5298     CHECK_REG_STR(prodkey, "Contact", NULL);
5299     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5300     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5301     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5302     CHECK_REG_STR(prodkey, "Readme", NULL);
5303     CHECK_REG_STR(prodkey, "Size", NULL);
5304     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5305     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5306     CHECK_REG_DWORD(prodkey, "Language", 1033);
5307     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5308     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5309     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5310     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5311     todo_wine
5312     {
5313         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
5314     }
5315
5316     RegCloseKey(prodkey);
5317
5318     /* UnpublishFeatures, both features removed */
5319     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
5320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5321     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5322     ok(!pf_exists("msitest"), "Directory not deleted\n");
5323
5324     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5325     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5326
5327     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5328     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5329
5330     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5331     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5332
5333     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5334                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5335     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5336     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5337
5338     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5339     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5340
5341     /* complete install */
5342     r = MsiInstallProductA(msifile, "FULL=1");
5343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5344     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5345     ok(pf_exists("msitest"), "File not installed\n");
5346
5347     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5348     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5349
5350     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5351     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5352
5353     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5354     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5355
5356     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5357                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5358     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5359     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5360
5361     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5363
5364     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5365     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5366     CHECK_REG_STR(prodkey, "InstallDate", date);
5367     CHECK_REG_STR(prodkey, "InstallSource", temp);
5368     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5369     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5370     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5371     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5372     CHECK_REG_STR(prodkey, "Comments", NULL);
5373     CHECK_REG_STR(prodkey, "Contact", NULL);
5374     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5375     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5376     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5377     CHECK_REG_STR(prodkey, "Readme", NULL);
5378     CHECK_REG_STR(prodkey, "Size", NULL);
5379     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5380     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5381     CHECK_REG_DWORD(prodkey, "Language", 1033);
5382     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5383     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5384     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5385     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5386     todo_wine
5387     {
5388         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5389     }
5390
5391     RegCloseKey(prodkey);
5392
5393     /* complete uninstall */
5394     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5395     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5396     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5397     ok(!pf_exists("msitest"), "Directory not deleted\n");
5398
5399     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5400     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5401
5402     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5403     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5404
5405     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5406     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5407
5408     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5409                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5410     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5411     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5412
5413     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5414     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5415
5416     /* make sure 'Program Files\msitest' is removed */
5417     delete_pfmsitest_files();
5418
5419     RegCloseKey(uninstall);
5420     DeleteFile(msifile);
5421     DeleteFile("msitest\\maximus");
5422     RemoveDirectory("msitest");
5423 }
5424
5425 static void test_publishsourcelist(void)
5426 {
5427     UINT r;
5428     DWORD size;
5429     CHAR value[MAX_PATH];
5430     CHAR path[MAX_PATH];
5431     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5432
5433     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
5434     {
5435         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
5436         return;
5437     }
5438
5439     CreateDirectoryA("msitest", NULL);
5440     create_file("msitest\\maximus", 500);
5441
5442     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5443
5444     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5445
5446     r = MsiInstallProductA(msifile, NULL);
5447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5448     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5449     ok(pf_exists("msitest"), "File not installed\n");
5450
5451     /* nothing published */
5452     size = MAX_PATH;
5453     lstrcpyA(value, "aaa");
5454     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5455                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5456     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5457     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5458     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5459
5460     size = MAX_PATH;
5461     lstrcpyA(value, "aaa");
5462     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5463                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5464     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5465     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5466     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5467
5468     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
5469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5470     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5471     ok(pf_exists("msitest"), "File not installed\n");
5472
5473     /* after RegisterProduct */
5474     size = MAX_PATH;
5475     lstrcpyA(value, "aaa");
5476     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5477                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5478     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5479     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5480     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5481
5482     size = MAX_PATH;
5483     lstrcpyA(value, "aaa");
5484     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5485                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5486     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5487     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5488     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5489
5490     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5492     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5493     ok(pf_exists("msitest"), "File not installed\n");
5494
5495     /* after ProcessComponents */
5496     size = MAX_PATH;
5497     lstrcpyA(value, "aaa");
5498     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5499                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5500     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5501     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5502     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5503
5504     size = MAX_PATH;
5505     lstrcpyA(value, "aaa");
5506     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5507                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5508     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5509     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5510     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5511
5512     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
5513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5514     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5515     ok(pf_exists("msitest"), "File not installed\n");
5516
5517     /* after PublishFeatures */
5518     size = MAX_PATH;
5519     lstrcpyA(value, "aaa");
5520     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5521                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5522     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5523     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5524     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5525
5526     size = MAX_PATH;
5527     lstrcpyA(value, "aaa");
5528     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5529                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5530     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5531     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5532     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5533
5534     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
5535     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5536     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5537     ok(pf_exists("msitest"), "File not installed\n");
5538
5539     /* after PublishProduct */
5540     size = MAX_PATH;
5541     lstrcpyA(value, "aaa");
5542     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5543                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5545     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
5546     ok(size == 11, "Expected 11, got %d\n", size);
5547
5548     size = MAX_PATH;
5549     lstrcpyA(value, "aaa");
5550     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5551                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
5552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5553     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5554     ok(size == 0, "Expected 0, got %d\n", size);
5555
5556     size = MAX_PATH;
5557     lstrcpyA(value, "aaa");
5558     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5559                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
5560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5561     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5562     ok(size == 0, "Expected 0, got %d\n", size);
5563
5564     lstrcpyA(path, CURR_DIR);
5565     lstrcatA(path, "\\");
5566
5567     size = MAX_PATH;
5568     lstrcpyA(value, "aaa");
5569     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5570                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
5571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5572     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5573     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5574
5575     size = MAX_PATH;
5576     lstrcpyA(value, "aaa");
5577     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5578                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
5579     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5580     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
5581     ok(size == 1, "Expected 1, got %d\n", size);
5582
5583     size = MAX_PATH;
5584     lstrcpyA(value, "aaa");
5585     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5586                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5587     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5588     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5589     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5590
5591     size = MAX_PATH;
5592     lstrcpyA(value, "aaa");
5593     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5594                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
5595     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5596     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5597     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5598
5599     size = MAX_PATH;
5600     lstrcpyA(value, "aaa");
5601     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5602                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
5603     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5604     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5605     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5606
5607     /* complete uninstall */
5608     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5609     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5610     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5611     ok(!pf_exists("msitest"), "Directory not deleted\n");
5612
5613     /* make sure 'Program Files\msitest' is removed */
5614     delete_pfmsitest_files();
5615
5616     DeleteFile(msifile);
5617     DeleteFile("msitest\\maximus");
5618     RemoveDirectory("msitest");
5619 }
5620
5621 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
5622 {
5623     MSIHANDLE hview = 0;
5624     UINT r;
5625
5626     r = MsiDatabaseOpenView(hdb, query, &hview);
5627     if(r != ERROR_SUCCESS)
5628         return r;
5629
5630     r = MsiViewExecute(hview, hrec);
5631     if(r == ERROR_SUCCESS)
5632         r = MsiViewClose(hview);
5633     MsiCloseHandle(hview);
5634     return r;
5635 }
5636
5637 static void set_transform_summary_info(void)
5638 {
5639     UINT r;
5640     MSIHANDLE suminfo = 0;
5641
5642     /* build summary info */
5643     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
5644     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
5645
5646     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
5647     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5648
5649     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
5650                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5651                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5652                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
5653     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
5654
5655     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
5656     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5657
5658     r = MsiSummaryInfoPersist(suminfo);
5659     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
5660
5661     r = MsiCloseHandle(suminfo);
5662     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
5663 }
5664
5665 static void generate_transform(void)
5666 {
5667     MSIHANDLE hdb1, hdb2;
5668     LPCSTR query;
5669     UINT r;
5670
5671     /* start with two identical databases */
5672     CopyFile(msifile, msifile2, FALSE);
5673
5674     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
5675     ok(r == ERROR_SUCCESS , "Failed to create database\n");
5676
5677     r = MsiDatabaseCommit(hdb1);
5678     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
5679
5680     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
5681     ok(r == ERROR_SUCCESS , "Failed to create database\n");
5682
5683     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
5684     r = run_query(hdb1, 0, query);
5685     ok(r == ERROR_SUCCESS, "failed to add property\n");
5686
5687     /* database needs to be committed */
5688     MsiDatabaseCommit(hdb1);
5689
5690     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
5691     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
5692
5693 #if 0  /* not implemented in wine yet */
5694     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
5695     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5696 #endif
5697
5698     MsiCloseHandle(hdb1);
5699     MsiCloseHandle(hdb2);
5700 }
5701
5702 /* data for generating a transform */
5703
5704 /* tables transform names - encoded as they would be in an msi database file */
5705 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
5706 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
5707 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
5708
5709 /* data in each table */
5710 static const char data1[] = /* _StringData */
5711     "propval";  /* all the strings squashed together */
5712
5713 static const WCHAR data2[] = { /* _StringPool */
5714 /*  len, refs */
5715     0,   0,    /* string 0 ''     */
5716     4,   1,    /* string 1 'prop' */
5717     3,   1,    /* string 2 'val'  */
5718 };
5719
5720 static const WCHAR data3[] = { /* Property */
5721     0x0201, 0x0001, 0x0002,
5722 };
5723
5724 static const struct {
5725     LPCWSTR name;
5726     const void *data;
5727     DWORD size;
5728 } table_transform_data[] =
5729 {
5730     { name1, data1, sizeof data1 - 1 },
5731     { name2, data2, sizeof data2 },
5732     { name3, data3, sizeof data3 },
5733 };
5734
5735 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
5736
5737 static void generate_transform_manual(void)
5738 {
5739     IStorage *stg = NULL;
5740     IStream *stm;
5741     WCHAR name[0x20];
5742     HRESULT r;
5743     DWORD i, count;
5744     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
5745
5746     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
5747
5748     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
5749
5750     r = StgCreateDocfile(name, mode, 0, &stg);
5751     ok(r == S_OK, "failed to create storage\n");
5752     if (!stg)
5753         return;
5754
5755     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
5756     ok(r == S_OK, "failed to set storage type\n");
5757
5758     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
5759     {
5760         r = IStorage_CreateStream(stg, table_transform_data[i].name,
5761                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
5762         if (FAILED(r))
5763         {
5764             ok(0, "failed to create stream %08x\n", r);
5765             continue;
5766         }
5767
5768         r = IStream_Write(stm, table_transform_data[i].data,
5769                           table_transform_data[i].size, &count);
5770         if (FAILED(r) || count != table_transform_data[i].size)
5771             ok(0, "failed to write stream\n");
5772         IStream_Release(stm);
5773     }
5774
5775     IStorage_Release(stg);
5776
5777     set_transform_summary_info();
5778 }
5779
5780 static void test_transformprop(void)
5781 {
5782     UINT r;
5783
5784     CreateDirectoryA("msitest", NULL);
5785     create_file("msitest\\augustus", 500);
5786
5787     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
5788
5789     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5790
5791     r = MsiInstallProductA(msifile, NULL);
5792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5793     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5794     ok(!delete_pf("msitest", FALSE), "File installed\n");
5795
5796     if (0)
5797         generate_transform();
5798     else
5799         generate_transform_manual();
5800
5801     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
5802     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5803     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5804     ok(delete_pf("msitest", FALSE), "File not installed\n");
5805
5806     /* Delete the files in the temp (current) folder */
5807     DeleteFile(msifile);
5808     DeleteFile(msifile2);
5809     DeleteFile(mstfile);
5810     DeleteFile("msitest\\augustus");
5811     RemoveDirectory("msitest");
5812 }
5813
5814 static void test_currentworkingdir(void)
5815 {
5816     UINT r;
5817     CHAR drive[MAX_PATH], path[MAX_PATH];
5818     LPSTR ptr;
5819
5820     CreateDirectoryA("msitest", NULL);
5821     create_file("msitest\\augustus", 500);
5822
5823     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
5824
5825     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5826
5827     CreateDirectoryA("diffdir", NULL);
5828     SetCurrentDirectoryA("diffdir");
5829
5830     sprintf(path, "..\\%s", msifile);
5831     r = MsiInstallProductA(path, NULL);
5832     todo_wine
5833     {
5834         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
5835         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5836         ok(!delete_pf("msitest", FALSE), "File installed\n");
5837     }
5838
5839     sprintf(path, "%s\\%s", CURR_DIR, msifile);
5840     r = MsiInstallProductA(path, NULL);
5841     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5842     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5843     ok(delete_pf("msitest", FALSE), "File not installed\n");
5844
5845     lstrcpyA(drive, CURR_DIR);
5846     drive[2] = '\\';
5847     drive[3] = '\0';
5848     SetCurrentDirectoryA(drive);
5849
5850     lstrcpy(path, CURR_DIR);
5851     if (path[lstrlenA(path) - 1] != '\\')
5852         lstrcatA(path, "\\");
5853     lstrcatA(path, msifile);
5854     ptr = strchr(path, ':');
5855     ptr +=2;
5856
5857     r = MsiInstallProductA(ptr, NULL);
5858     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5859     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5860     ok(delete_pf("msitest", FALSE), "File not installed\n");
5861
5862     SetCurrentDirectoryA(CURR_DIR);
5863
5864     DeleteFile(msifile);
5865     DeleteFile("msitest\\augustus");
5866     RemoveDirectory("msitest");
5867     RemoveDirectory("diffdir");
5868 }
5869
5870 static void set_admin_summary_info(const CHAR *name)
5871 {
5872     MSIHANDLE db, summary;
5873     UINT r;
5874
5875     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
5876     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5877
5878     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
5879     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5880
5881     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
5882     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5883
5884     /* write the summary changes back to the stream */
5885     r = MsiSummaryInfoPersist(summary);
5886     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5887
5888     MsiCloseHandle(summary);
5889
5890     r = MsiDatabaseCommit(db);
5891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5892
5893     MsiCloseHandle(db);
5894 }
5895
5896 static void test_admin(void)
5897 {
5898     UINT r;
5899
5900     CreateDirectoryA("msitest", NULL);
5901     create_file("msitest\\augustus", 500);
5902
5903     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
5904     set_admin_summary_info(msifile);
5905
5906     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5907
5908     r = MsiInstallProductA(msifile, NULL);
5909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5910     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5911     ok(!delete_pf("msitest", FALSE), "File installed\n");
5912     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
5913     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
5914
5915     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
5916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5917     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5918     ok(!delete_pf("msitest", FALSE), "File installed\n");
5919     todo_wine
5920     {
5921         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
5922         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
5923     }
5924
5925     DeleteFile(msifile);
5926     DeleteFile("msitest\\augustus");
5927     RemoveDirectory("msitest");
5928 }
5929
5930 static void set_admin_property_stream(LPCSTR file)
5931 {
5932     IStorage *stg;
5933     IStream *stm;
5934     WCHAR fileW[MAX_PATH];
5935     HRESULT hr;
5936     DWORD count;
5937     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
5938
5939     /* AdminProperties */
5940     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
5941     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
5942         'M','y','P','r','o','p','=','4','2',0};
5943
5944     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
5945
5946     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
5947     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5948     if (!stg)
5949         return;
5950
5951     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
5952     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5953
5954     hr = IStream_Write(stm, data, sizeof(data), &count);
5955     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5956
5957     IStream_Release(stm);
5958     IStorage_Release(stg);
5959 }
5960
5961 static void test_adminprops(void)
5962 {
5963     UINT r;
5964
5965     CreateDirectoryA("msitest", NULL);
5966     create_file("msitest\\augustus", 500);
5967
5968     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
5969     set_admin_summary_info(msifile);
5970     set_admin_property_stream(msifile);
5971
5972     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5973
5974     r = MsiInstallProductA(msifile, NULL);
5975     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5976     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5977     ok(delete_pf("msitest", FALSE), "File installed\n");
5978
5979     DeleteFile(msifile);
5980     DeleteFile("msitest\\augustus");
5981     RemoveDirectory("msitest");
5982 }
5983
5984 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
5985 {
5986     CHAR path[MAX_PATH];
5987
5988     lstrcpyA(path, PROG_FILES_DIR);
5989     lstrcatA(path, "\\");
5990     lstrcatA(path, file);
5991
5992     if (is_file)
5993         create_file_data(path, data, 500);
5994     else
5995         CreateDirectoryA(path, NULL);
5996 }
5997
5998 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
5999
6000 static void test_removefiles(void)
6001 {
6002     UINT r;
6003
6004     CreateDirectoryA("msitest", NULL);
6005     create_file("msitest\\hydrogen", 500);
6006     create_file("msitest\\helium", 500);
6007     create_file("msitest\\lithium", 500);
6008
6009     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
6010
6011     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6012
6013     r = MsiInstallProductA(msifile, NULL);
6014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6015     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6016     ok(!pf_exists("msitest\\helium"), "File installed\n");
6017     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6018     ok(pf_exists("msitest"), "File not installed\n");
6019
6020     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6022     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6023     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
6024     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6025     ok(delete_pf("msitest", FALSE), "File deleted\n");
6026
6027     create_pf("msitest", FALSE);
6028     create_pf("msitest\\hydrogen", TRUE);
6029     create_pf("msitest\\helium", TRUE);
6030     create_pf("msitest\\lithium", TRUE);
6031
6032     r = MsiInstallProductA(msifile, NULL);
6033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6034     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6035     ok(pf_exists("msitest\\helium"), "File not installed\n");
6036     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6037     ok(pf_exists("msitest"), "File not installed\n");
6038
6039     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6040     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6041     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6042     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
6043     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6044     ok(delete_pf("msitest", FALSE), "File deleted\n");
6045
6046     create_pf("msitest", FALSE);
6047     create_pf("msitest\\furlong", TRUE);
6048     create_pf("msitest\\firkin", TRUE);
6049     create_pf("msitest\\fortnight", TRUE);
6050     create_pf("msitest\\becquerel", TRUE);
6051     create_pf("msitest\\dioptre", TRUE);
6052     create_pf("msitest\\attoparsec", TRUE);
6053     create_pf("msitest\\storeys", TRUE);
6054     create_pf("msitest\\block", TRUE);
6055     create_pf("msitest\\siriometer", TRUE);
6056     create_pf("msitest\\cabout", FALSE);
6057     create_pf("msitest\\cabout\\blocker", TRUE);
6058
6059     r = MsiInstallProductA(msifile, NULL);
6060     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6061     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6062     ok(!pf_exists("msitest\\helium"), "File installed\n");
6063     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6064     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
6065     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
6066     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
6067     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
6068     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
6069     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
6070     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
6071     ok(!pf_exists("msitest\\block"), "File not deleted\n");
6072     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
6073     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
6074     ok(pf_exists("msitest"), "File not installed\n");
6075
6076     create_pf("msitest\\furlong", TRUE);
6077     create_pf("msitest\\firkin", TRUE);
6078     create_pf("msitest\\fortnight", TRUE);
6079     create_pf("msitest\\storeys", TRUE);
6080     create_pf("msitest\\block", TRUE);
6081     create_pf("msitest\\siriometer", TRUE);
6082
6083     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6084     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6085     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
6086     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
6087     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6088     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
6089     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
6090     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
6091     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
6092     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
6093     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
6094     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
6095     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
6096     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
6097     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6098     ok(pf_exists("msitest"), "Directory deleted\n");
6099
6100     r = MsiInstallProductA(msifile, NULL);
6101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6102     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
6103     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
6104     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
6105     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6106     ok(pf_exists("msitest"), "Directory deleted\n");
6107
6108     delete_pf("msitest\\cabout\\blocker", TRUE);
6109
6110     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6112     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
6113     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
6114
6115     DeleteFile(msifile);
6116     DeleteFile("msitest\\hydrogen");
6117     DeleteFile("msitest\\helium");
6118     DeleteFile("msitest\\lithium");
6119     RemoveDirectory("msitest");
6120 }
6121
6122 static void test_movefiles(void)
6123 {
6124     UINT r;
6125     char props[MAX_PATH];
6126
6127     CreateDirectoryA("msitest", NULL);
6128     create_file("msitest\\augustus", 100);
6129     create_file("cameroon", 100);
6130     create_file("djibouti", 100);
6131     create_file("egypt", 100);
6132     create_file("finland", 100);
6133     create_file("gambai", 100);
6134     create_file("honduras", 100);
6135     create_file("msitest\\india", 100);
6136     create_file("japan", 100);
6137     create_file("kenya", 100);
6138     CreateDirectoryA("latvia", NULL);
6139     create_file("nauru", 100);
6140     create_file("peru", 100);
6141     create_file("apple", 100);
6142     create_file("application", 100);
6143     create_file("ape", 100);
6144     create_file("foo", 100);
6145     create_file("fao", 100);
6146     create_file("fbod", 100);
6147     create_file("budding", 100);
6148     create_file("buddy", 100);
6149     create_file("bud", 100);
6150     create_file("bar", 100);
6151     create_file("bur", 100);
6152     create_file("bird", 100);
6153
6154     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
6155
6156     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6157
6158     /* if the source or dest property is not a full path,
6159      * windows tries to access it as a network resource
6160      */
6161
6162     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
6163             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
6164             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
6165
6166     r = MsiInstallProductA(msifile, props);
6167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6168     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6169     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
6170     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
6171     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
6172     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
6173     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
6174     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
6175     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
6176     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
6177     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
6178     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
6179     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
6180     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
6181     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
6182     /* either apple or application will be moved depending on directory order */
6183     if (!delete_pf("msitest\\apple", TRUE))
6184         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
6185     else
6186         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
6187     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
6188     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
6189     /* either fao or foo will be moved depending on directory order */
6190     if (delete_pf("msitest\\foo", TRUE))
6191         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
6192     else
6193         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
6194     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
6195     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
6196     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
6197     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
6198     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
6199     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
6200     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
6201     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
6202     ok(delete_pf("msitest", FALSE), "File not installed\n");
6203     ok(DeleteFileA("cameroon"), "File moved\n");
6204     ok(!DeleteFileA("djibouti"), "File not moved\n");
6205     ok(DeleteFileA("egypt"), "File moved\n");
6206     ok(DeleteFileA("finland"), "File moved\n");
6207     ok(DeleteFileA("gambai"), "File moved\n");
6208     ok(!DeleteFileA("honduras"), "File not moved\n");
6209     ok(DeleteFileA("msitest\\india"), "File moved\n");
6210     ok(DeleteFileA("japan"), "File moved\n");
6211     ok(!DeleteFileA("kenya"), "File not moved\n");
6212     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
6213     ok(!DeleteFileA("nauru"), "File not moved\n");
6214     ok(!DeleteFileA("peru"), "File not moved\n");
6215     ok(!DeleteFileA("apple"), "File not moved\n");
6216     ok(!DeleteFileA("application"), "File not moved\n");
6217     ok(DeleteFileA("ape"), "File moved\n");
6218     ok(!DeleteFileA("foo"), "File not moved\n");
6219     ok(!DeleteFileA("fao"), "File not moved\n");
6220     ok(DeleteFileA("fbod"), "File moved\n");
6221     ok(!DeleteFileA("budding"), "File not moved\n");
6222     ok(!DeleteFileA("buddy"), "File not moved\n");
6223     ok(DeleteFileA("bud"), "File moved\n");
6224     ok(!DeleteFileA("bar"), "File not moved\n");
6225     ok(!DeleteFileA("bur"), "File not moved\n");
6226     ok(DeleteFileA("bird"), "File moved\n");
6227
6228     DeleteFile("msitest\\augustus");
6229     RemoveDirectory("msitest");
6230     DeleteFile(msifile);
6231 }
6232
6233 static void test_missingcab(void)
6234 {
6235     UINT r;
6236
6237     CreateDirectoryA("msitest", NULL);
6238     create_file("msitest\\augustus", 500);
6239     create_file("maximus", 500);
6240
6241     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
6242
6243     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6244
6245     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6246
6247     create_pf("msitest", FALSE);
6248     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6249
6250     r = MsiInstallProductA(msifile, NULL);
6251     ok(r == ERROR_SUCCESS ||
6252        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
6253        "Expected ERROR_SUCCESS, got %u\n", r);
6254     if (r == ERROR_SUCCESS)
6255     {
6256       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6257       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6258     }
6259     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
6260     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
6261     ok(delete_pf("msitest", FALSE), "File not installed\n");
6262
6263     create_pf("msitest", FALSE);
6264     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6265     create_pf("msitest\\gaius", TRUE);
6266
6267     r = MsiInstallProductA(msifile, "GAIUS=1");
6268     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6269     todo_wine
6270     {
6271         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
6272         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6273     }
6274     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
6275     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
6276     ok(delete_pf("msitest", FALSE), "File not installed\n");
6277
6278     DeleteFile("msitest\\augustus");
6279     RemoveDirectory("msitest");
6280     DeleteFile("maximus");
6281     DeleteFile("test1.cab");
6282     DeleteFile(msifile);
6283 }
6284
6285 static void test_duplicatefiles(void)
6286 {
6287     UINT r;
6288
6289     CreateDirectoryA("msitest", NULL);
6290     create_file("msitest\\maximus", 500);
6291     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
6292
6293     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6294
6295     /* fails if the destination folder is not a valid property */
6296
6297     r = MsiInstallProductA(msifile, NULL);
6298     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6299     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6300     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
6301     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
6302     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
6303     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
6304     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
6305     ok(delete_pf("msitest", FALSE), "File not installed\n");
6306
6307     DeleteFile("msitest\\maximus");
6308     RemoveDirectory("msitest");
6309     DeleteFile(msifile);
6310 }
6311
6312 static void test_writeregistryvalues(void)
6313 {
6314     UINT r;
6315     LONG res;
6316     HKEY hkey;
6317     DWORD type, size;
6318     CHAR path[MAX_PATH];
6319
6320     CreateDirectoryA("msitest", NULL);
6321     create_file("msitest\\augustus", 500);
6322
6323     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
6324
6325     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6326
6327     r = MsiInstallProductA(msifile, NULL);
6328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6329     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6330     ok(delete_pf("msitest", FALSE), "File installed\n");
6331
6332     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
6333     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6334
6335     size = MAX_PATH;
6336     type = REG_MULTI_SZ;
6337     memset(path, 'a', MAX_PATH);
6338     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
6339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6340     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
6341     ok(size == 15, "Expected 15, got %d\n", size);
6342     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
6343
6344     DeleteFile(msifile);
6345     DeleteFile("msitest\\augustus");
6346     RemoveDirectory("msitest");
6347
6348     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
6349     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
6350 }
6351
6352 static void test_sourcefolder(void)
6353 {
6354     UINT r;
6355
6356     CreateDirectoryA("msitest", NULL);
6357     create_file("augustus", 500);
6358
6359     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
6360
6361     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6362
6363     r = MsiInstallProductA(msifile, NULL);
6364     ok(r == ERROR_INSTALL_FAILURE,
6365        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6366     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6367     todo_wine
6368     {
6369         ok(!delete_pf("msitest", FALSE), "File installed\n");
6370     }
6371
6372     RemoveDirectoryA("msitest");
6373
6374     r = MsiInstallProductA(msifile, NULL);
6375     ok(r == ERROR_INSTALL_FAILURE,
6376        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6377     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6378     todo_wine
6379     {
6380         ok(!delete_pf("msitest", FALSE), "File installed\n");
6381     }
6382
6383     DeleteFile(msifile);
6384     DeleteFile("augustus");
6385 }
6386
6387 static void test_customaction51(void)
6388 {
6389     UINT r;
6390
6391     CreateDirectoryA("msitest", NULL);
6392     create_file("msitest\\augustus", 500);
6393
6394     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6395
6396     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6397
6398     r = MsiInstallProductA(msifile, NULL);
6399     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6400     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6401     ok(delete_pf("msitest", FALSE), "File installed\n");
6402
6403     DeleteFile(msifile);
6404     DeleteFile("msitest\\augustus");
6405     RemoveDirectory("msitest");
6406 }
6407
6408 static void test_installstate(void)
6409 {
6410     UINT r;
6411
6412     CreateDirectoryA("msitest", NULL);
6413     create_file("msitest\\alpha", 500);
6414     create_file("msitest\\beta", 500);
6415     create_file("msitest\\gamma", 500);
6416     create_file("msitest\\theta", 500);
6417     create_file("msitest\\delta", 500);
6418     create_file("msitest\\epsilon", 500);
6419     create_file("msitest\\zeta", 500);
6420     create_file("msitest\\iota", 500);
6421     create_file("msitest\\eta", 500);
6422     create_file("msitest\\kappa", 500);
6423     create_file("msitest\\lambda", 500);
6424     create_file("msitest\\mu", 500);
6425
6426     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
6427
6428     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6429
6430     r = MsiInstallProductA(msifile, NULL);
6431     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6432     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6433     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6434     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6435     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6436     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6437     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6438     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6439     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6440     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6441     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6442     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6443     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6444     ok(delete_pf("msitest", FALSE), "File not installed\n");
6445
6446     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
6447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6448     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6449     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6450     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6451     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6452     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6453     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
6454     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6455     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6456     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
6457     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6458     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6459     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6460     ok(delete_pf("msitest", FALSE), "File not installed\n");
6461
6462     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
6463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6464     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6465     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6466     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6467     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6468     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6469     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6470     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6471     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6472     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6473     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6474     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6475     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6476     ok(delete_pf("msitest", FALSE), "File not installed\n");
6477
6478     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
6479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6480     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
6481     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6482     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6483     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
6484     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6485     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6486     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6487     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6488     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6489     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6490     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6491     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6492     ok(!delete_pf("msitest", FALSE), "File installed\n");
6493
6494     DeleteFile(msifile);
6495     DeleteFile("msitest\\alpha");
6496     DeleteFile("msitest\\beta");
6497     DeleteFile("msitest\\gamma");
6498     DeleteFile("msitest\\theta");
6499     DeleteFile("msitest\\delta");
6500     DeleteFile("msitest\\epsilon");
6501     DeleteFile("msitest\\zeta");
6502     DeleteFile("msitest\\iota");
6503     DeleteFile("msitest\\eta");
6504     DeleteFile("msitest\\kappa");
6505     DeleteFile("msitest\\lambda");
6506     DeleteFile("msitest\\mu");
6507     RemoveDirectory("msitest");
6508 }
6509
6510 struct sourcepathmap
6511 {
6512     BOOL sost; /* shortone\shorttwo */
6513     BOOL solt; /* shortone\longtwo */
6514     BOOL lost; /* longone\shorttwo */
6515     BOOL lolt; /* longone\longtwo */
6516     BOOL soste; /* shortone\shorttwo source exists */
6517     BOOL solte; /* shortone\longtwo source exists */
6518     BOOL loste; /* longone\shorttwo source exists */
6519     BOOL lolte; /* longone\longtwo source exists */
6520     UINT err;
6521     DWORD size;
6522 } spmap[256] =
6523 {
6524     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6525     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6526     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6527     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6528     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6529     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6530     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6531     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6532     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6533     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6534     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6535     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6536     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6537     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6538     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6539     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6540     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6541     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6542     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6543     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6544     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6545     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6546     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6547     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6548     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6549     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6550     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6551     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6552     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6553     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6554     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6555     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6556     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6557     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6558     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6559     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6560     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6561     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6562     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6563     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6564     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6565     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6566     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6567     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6568     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6569     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6570     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6571     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6572     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6573     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6574     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6575     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6576     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6577     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6578     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6579     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6580     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6581     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6582     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6583     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6584     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6585     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6586     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6587     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6588     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6589     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6590     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6591     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6592     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6593     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6594     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6595     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6596     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6597     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6598     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6599     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6600     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6601     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6602     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6603     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6604     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6605     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6606     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6607     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6608     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6609     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6610     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6611     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6612     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6613     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6614     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6615     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6616     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6617     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6618     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6619     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6620     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6621     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6622     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6623     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6624     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6625     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6626     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6627     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6628     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6629     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6630     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6631     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6632     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6633     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6634     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6635     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6636     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6637     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6638     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6639     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6640     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6641     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6642     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6643     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6644     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6645     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6646     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6647     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6648     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6649     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6650     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6651     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6652     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6653     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6654     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6655     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6656     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6657     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6658     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6659     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6660     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6661     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6662     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6663     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6664     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6665     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6666     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6667     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6668     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6669     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6670     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6671     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6672     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6673     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6674     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6675     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6676     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6677     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6678     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6679     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6680     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6681     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6682     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6683     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6684     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6685     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6686     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6687     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6688     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6689     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6690     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6691     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6692     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6693     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6694     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6695     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6696     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6697     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6698     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6699     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6700     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6701     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6702     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6703     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6704     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6705     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6706     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6707     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6708     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6709     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6710     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6711     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6712     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6713     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6714     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6715     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6716     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6717     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6718     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6719     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6720     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6721     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6722     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6723     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6724     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6725     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6726     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6727     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6728     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6729     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6730     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6731     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6732     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6733     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6734     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6735     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6736     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6737     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6738     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6739     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6740     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6741     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6742     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6743     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6744     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6745     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6746     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6747     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6748     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6749     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6750     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6751     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6752     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6753     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6754     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6755     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6756     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6757     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6758     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6759     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6760     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6761     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6762     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6763     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6764     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6765     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6766     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6767     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6768     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6769     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6770     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6771     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6772     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6773     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6774     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6775     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6776     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6777     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6778     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6779     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6780 };
6781
6782 static DWORD get_pf_file_size(LPCSTR file)
6783 {
6784     CHAR path[MAX_PATH];
6785     HANDLE hfile;
6786     DWORD size;
6787
6788     lstrcpyA(path, PROG_FILES_DIR);
6789     lstrcatA(path, "\\");
6790     lstrcatA(path, file);
6791
6792     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
6793     if (hfile == INVALID_HANDLE_VALUE)
6794         return 0;
6795
6796     size = GetFileSize(hfile, NULL);
6797     CloseHandle(hfile);
6798     return size;
6799 }
6800
6801 static void test_sourcepath(void)
6802 {
6803     UINT r, i;
6804
6805     if (!winetest_interactive)
6806     {
6807         skip("Run in interactive mode to run source path tests.\n");
6808         return;
6809     }
6810
6811     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
6812
6813     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6814
6815     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
6816     {
6817         if (spmap[i].sost)
6818         {
6819             CreateDirectoryA("shortone", NULL);
6820             CreateDirectoryA("shortone\\shorttwo", NULL);
6821         }
6822
6823         if (spmap[i].solt)
6824         {
6825             CreateDirectoryA("shortone", NULL);
6826             CreateDirectoryA("shortone\\longtwo", NULL);
6827         }
6828
6829         if (spmap[i].lost)
6830         {
6831             CreateDirectoryA("longone", NULL);
6832             CreateDirectoryA("longone\\shorttwo", NULL);
6833         }
6834
6835         if (spmap[i].lolt)
6836         {
6837             CreateDirectoryA("longone", NULL);
6838             CreateDirectoryA("longone\\longtwo", NULL);
6839         }
6840
6841         if (spmap[i].soste)
6842             create_file("shortone\\shorttwo\\augustus", 50);
6843         if (spmap[i].solte)
6844             create_file("shortone\\longtwo\\augustus", 100);
6845         if (spmap[i].loste)
6846             create_file("longone\\shorttwo\\augustus", 150);
6847         if (spmap[i].lolte)
6848             create_file("longone\\longtwo\\augustus", 200);
6849
6850         r = MsiInstallProductA(msifile, NULL);
6851         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
6852         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
6853            "%d: Expected %d, got %d\n", i, spmap[i].size,
6854            get_pf_file_size("msitest\\augustus"));
6855
6856         if (r == ERROR_SUCCESS)
6857         {
6858             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
6859             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
6860         }
6861         else
6862         {
6863             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
6864             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
6865         }
6866
6867         DeleteFileA("shortone\\shorttwo\\augustus");
6868         DeleteFileA("shortone\\longtwo\\augustus");
6869         DeleteFileA("longone\\shorttwo\\augustus");
6870         DeleteFileA("longone\\longtwo\\augustus");
6871         RemoveDirectoryA("shortone\\shorttwo");
6872         RemoveDirectoryA("shortone\\longtwo");
6873         RemoveDirectoryA("longone\\shorttwo");
6874         RemoveDirectoryA("longone\\longtwo");
6875         RemoveDirectoryA("shortone");
6876         RemoveDirectoryA("longone");
6877     }
6878
6879     DeleteFileA(msifile);
6880 }
6881
6882 static void test_MsiConfigureProductEx(void)
6883 {
6884     UINT r;
6885     LONG res;
6886     DWORD type, size;
6887     HKEY props, source;
6888     CHAR keypath[MAX_PATH * 2];
6889     CHAR localpack[MAX_PATH];
6890
6891     if (on_win9x)
6892     {
6893         win_skip("Different registry keys on Win9x and WinMe\n");
6894         return;
6895     }
6896
6897     CreateDirectoryA("msitest", NULL);
6898     create_file("msitest\\hydrogen", 500);
6899     create_file("msitest\\helium", 500);
6900     create_file("msitest\\lithium", 500);
6901
6902     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6903
6904     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6905
6906     /* NULL szProduct */
6907     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
6908                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6909     ok(r == ERROR_INVALID_PARAMETER,
6910        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6911
6912     /* empty szProduct */
6913     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
6914                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6915     ok(r == ERROR_INVALID_PARAMETER,
6916        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6917
6918     /* garbage szProduct */
6919     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
6920                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6921     ok(r == ERROR_INVALID_PARAMETER,
6922        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6923
6924     /* guid without brackets */
6925     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6926                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6927                                "PROPVAR=42");
6928     ok(r == ERROR_INVALID_PARAMETER,
6929        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6930
6931     /* guid with brackets */
6932     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6933                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6934                                "PROPVAR=42");
6935     ok(r == ERROR_UNKNOWN_PRODUCT,
6936        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6937
6938     /* same length as guid, but random */
6939     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
6940                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6941                                "PROPVAR=42");
6942     ok(r == ERROR_UNKNOWN_PRODUCT,
6943        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6944
6945     /* product not installed yet */
6946     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6947                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6948                                "PROPVAR=42");
6949     ok(r == ERROR_UNKNOWN_PRODUCT,
6950        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6951
6952     /* install the product, per-user unmanaged */
6953     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
6954     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6955     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6956     ok(pf_exists("msitest\\helium"), "File not installed\n");
6957     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6958     ok(pf_exists("msitest"), "File not installed\n");
6959
6960     /* product is installed per-user managed, remove it */
6961     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6962                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6963                                "PROPVAR=42");
6964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6965     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6966     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6967     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6968     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
6969
6970     /* product has been removed */
6971     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6972                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6973                                "PROPVAR=42");
6974     ok(r == ERROR_UNKNOWN_PRODUCT,
6975        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
6976
6977     /* install the product, machine */
6978     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6980     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6981     ok(pf_exists("msitest\\helium"), "File not installed\n");
6982     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6983     ok(pf_exists("msitest"), "File not installed\n");
6984
6985     /* product is installed machine, remove it */
6986     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6987                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6988                                "PROPVAR=42");
6989     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6990     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6991     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6992     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6993     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
6994
6995     /* product has been removed */
6996     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6997                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6998                                "PROPVAR=42");
6999     ok(r == ERROR_UNKNOWN_PRODUCT,
7000        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7001
7002     /* install the product, machine */
7003     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7005     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7006     ok(pf_exists("msitest\\helium"), "File not installed\n");
7007     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7008     ok(pf_exists("msitest"), "File not installed\n");
7009
7010     DeleteFileA(msifile);
7011
7012     /* local msifile is removed */
7013     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7014                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7015                                "PROPVAR=42");
7016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7017     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7018     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7019     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7020     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7021
7022     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7023
7024     /* install the product, machine */
7025     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7027     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7028     ok(pf_exists("msitest\\helium"), "File not installed\n");
7029     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7030     ok(pf_exists("msitest"), "File not installed\n");
7031
7032     DeleteFileA(msifile);
7033
7034     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7035     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7036     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7037
7038     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7040
7041     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7042                          (const BYTE *)"C:\\idontexist.msi", 18);
7043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7044
7045     /* LocalPackage is used to find the cached msi package */
7046     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7047                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7048                                "PROPVAR=42");
7049     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7050        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7051     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7052     ok(pf_exists("msitest\\helium"), "File not installed\n");
7053     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7054     ok(pf_exists("msitest"), "File not installed\n");
7055
7056     RegCloseKey(props);
7057     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7058
7059     /* LastUsedSource (local msi package) can be used as a last resort */
7060     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7061                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7062                                "PROPVAR=42");
7063     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7064     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7065     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7066     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7067     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7068
7069     /* install the product, machine */
7070     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7072     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7073     ok(pf_exists("msitest\\helium"), "File not installed\n");
7074     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7075     ok(pf_exists("msitest"), "File not installed\n");
7076
7077     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7078     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7079     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7080
7081     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7083
7084     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7085                          (const BYTE *)"C:\\idontexist.msi", 18);
7086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7087
7088     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
7089     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
7090
7091     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
7092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7093
7094     type = REG_SZ;
7095     size = MAX_PATH;
7096     res = RegQueryValueExA(source, "PackageName", NULL, &type,
7097                            (LPBYTE)localpack, &size);
7098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7099
7100     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7101                          (const BYTE *)"idontexist.msi", 15);
7102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7103
7104     /* SourceList is altered */
7105     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7106                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7107                                "PROPVAR=42");
7108     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7109        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7110     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7111     ok(pf_exists("msitest\\helium"), "File not installed\n");
7112     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7113     ok(pf_exists("msitest"), "File not installed\n");
7114
7115     /* restore the SourceList */
7116     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7117                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
7118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7119
7120     /* finally remove the product */
7121     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7122                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7123                                "PROPVAR=42");
7124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7125     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7126     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7127     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7128     ok(!delete_pf("msitest", FALSE), "File not removed\n");
7129
7130     DeleteFileA(msifile);
7131     RegCloseKey(source);
7132     RegCloseKey(props);
7133     DeleteFileA("msitest\\hydrogen");
7134     DeleteFileA("msitest\\helium");
7135     DeleteFileA("msitest\\lithium");
7136     RemoveDirectoryA("msitest");
7137 }
7138
7139 static void test_missingcomponent(void)
7140 {
7141     UINT r;
7142
7143     CreateDirectoryA("msitest", NULL);
7144     create_file("msitest\\hydrogen", 500);
7145     create_file("msitest\\helium", 500);
7146     create_file("msitest\\lithium", 500);
7147     create_file("beryllium", 500);
7148
7149     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
7150
7151     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7152
7153     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7154     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7155     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7156     ok(pf_exists("msitest\\helium"), "File not installed\n");
7157     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7158     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7159     ok(pf_exists("msitest"), "File not installed\n");
7160
7161     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
7162     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7163     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7164     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7165     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7166     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7167     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7168
7169     DeleteFileA(msifile);
7170     DeleteFileA("msitest\\hydrogen");
7171     DeleteFileA("msitest\\helium");
7172     DeleteFileA("msitest\\lithium");
7173     DeleteFileA("beryllium");
7174     RemoveDirectoryA("msitest");
7175 }
7176
7177 static void test_sourcedirprop(void)
7178 {
7179     UINT r;
7180     CHAR props[MAX_PATH];
7181
7182     CreateDirectoryA("msitest", NULL);
7183     create_file("msitest\\augustus", 500);
7184
7185     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
7186
7187     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7188
7189     r = MsiInstallProductA(msifile, NULL);
7190     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7191     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7192     ok(delete_pf("msitest", FALSE), "File installed\n");
7193
7194     DeleteFile("msitest\\augustus");
7195     RemoveDirectory("msitest");
7196
7197     CreateDirectoryA("altsource", NULL);
7198     CreateDirectoryA("altsource\\msitest", NULL);
7199     create_file("altsource\\msitest\\augustus", 500);
7200
7201     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
7202
7203     r = MsiInstallProductA(msifile, props);
7204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7205     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7206     ok(delete_pf("msitest", FALSE), "File installed\n");
7207
7208     DeleteFile(msifile);
7209     DeleteFile("altsource\\msitest\\augustus");
7210     RemoveDirectory("altsource\\msitest");
7211     RemoveDirectory("altsource");
7212 }
7213
7214 static void test_adminimage(void)
7215 {
7216     UINT r;
7217
7218     CreateDirectoryA("msitest", NULL);
7219     CreateDirectoryA("msitest\\first", NULL);
7220     CreateDirectoryA("msitest\\second", NULL);
7221     CreateDirectoryA("msitest\\cabout", NULL);
7222     CreateDirectoryA("msitest\\cabout\\new", NULL);
7223     create_file("msitest\\one.txt", 100);
7224     create_file("msitest\\first\\two.txt", 100);
7225     create_file("msitest\\second\\three.txt", 100);
7226     create_file("msitest\\cabout\\four.txt", 100);
7227     create_file("msitest\\cabout\\new\\five.txt", 100);
7228     create_file("msitest\\filename", 100);
7229     create_file("msitest\\service.exe", 100);
7230
7231     create_database_wordcount(msifile, ai_tables,
7232                               sizeof(ai_tables) / sizeof(msi_table),
7233                               msidbSumInfoSourceTypeAdminImage);
7234
7235     r = MsiInstallProductA(msifile, NULL);
7236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7237
7238     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7239     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7240     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7241     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7242     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7243     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7244     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7245     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7246     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7247     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7248     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7249     ok(delete_pf("msitest", FALSE), "File not installed\n");
7250
7251     DeleteFileA("msitest.msi");
7252     DeleteFileA("msitest\\cabout\\new\\five.txt");
7253     DeleteFileA("msitest\\cabout\\four.txt");
7254     DeleteFileA("msitest\\second\\three.txt");
7255     DeleteFileA("msitest\\first\\two.txt");
7256     DeleteFileA("msitest\\one.txt");
7257     DeleteFileA("msitest\\service.exe");
7258     DeleteFileA("msitest\\filename");
7259     RemoveDirectoryA("msitest\\cabout\\new");
7260     RemoveDirectoryA("msitest\\cabout");
7261     RemoveDirectoryA("msitest\\second");
7262     RemoveDirectoryA("msitest\\first");
7263     RemoveDirectoryA("msitest");
7264 }
7265
7266 static void test_propcase(void)
7267 {
7268     UINT r;
7269
7270     CreateDirectoryA("msitest", NULL);
7271     create_file("msitest\\augustus", 500);
7272
7273     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
7274
7275     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7276
7277     r = MsiInstallProductA(msifile, "MyProp=42");
7278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7279     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
7280     ok(delete_pf("msitest", FALSE), "File not installed\n");
7281
7282     DeleteFile(msifile);
7283     DeleteFile("msitest\\augustus");
7284     RemoveDirectory("msitest");
7285 }
7286
7287 static void test_int_widths( void )
7288 {
7289     static const char int0[] = "int0\ni0\nint0\tint0\n1";
7290     static const char int1[] = "int1\ni1\nint1\tint1\n1";
7291     static const char int2[] = "int2\ni2\nint2\tint2\n1";
7292     static const char int3[] = "int3\ni3\nint3\tint3\n1";
7293     static const char int4[] = "int4\ni4\nint4\tint4\n1";
7294     static const char int5[] = "int5\ni5\nint5\tint5\n1";
7295     static const char int8[] = "int8\ni8\nint8\tint8\n1";
7296
7297     static const struct
7298     {
7299         const char  *data;
7300         unsigned int size;
7301         UINT         ret;
7302     }
7303     tests[] =
7304     {
7305         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
7306         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
7307         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
7308         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
7309         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
7310         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
7311         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
7312     };
7313
7314     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
7315     MSIHANDLE db;
7316     UINT r, i;
7317
7318     GetTempPathA(MAX_PATH, tmpdir);
7319     CreateDirectoryA(tmpdir, NULL);
7320
7321     strcpy(msitable, tmpdir);
7322     strcat(msitable, "\\msitable.idt");
7323
7324     strcpy(msidb, tmpdir);
7325     strcat(msidb, "\\msitest.msi");
7326
7327     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
7328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7329
7330     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
7331     {
7332         write_file(msitable, tests[i].data, tests[i].size);
7333
7334         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
7335         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
7336
7337         r = MsiDatabaseCommit(db);
7338         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7339         DeleteFileA(msitable);
7340     }
7341
7342     MsiCloseHandle(db);
7343     DeleteFileA(msidb);
7344     RemoveDirectoryA(tmpdir);
7345 }
7346
7347 static void test_shortcut(void)
7348 {
7349     UINT r;
7350     HRESULT hr;
7351
7352     create_test_files();
7353     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
7354
7355     r = MsiInstallProductA(msifile, NULL);
7356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7357
7358     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
7359     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7360
7361     r = MsiInstallProductA(msifile, NULL);
7362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7363
7364     CoUninitialize();
7365
7366     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7367     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7368
7369     r = MsiInstallProductA(msifile, NULL);
7370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7371
7372     CoUninitialize();
7373
7374     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7375     delete_pf("msitest\\cabout\\new", FALSE);
7376     delete_pf("msitest\\cabout\\four.txt", TRUE);
7377     delete_pf("msitest\\cabout", FALSE);
7378     delete_pf("msitest\\changed\\three.txt", TRUE);
7379     delete_pf("msitest\\changed", FALSE);
7380     delete_pf("msitest\\first\\two.txt", TRUE);
7381     delete_pf("msitest\\first", FALSE);
7382     delete_pf("msitest\\filename", TRUE);
7383     delete_pf("msitest\\one.txt", TRUE);
7384     delete_pf("msitest\\service.exe", TRUE);
7385     delete_pf("msitest\\Shortcut.lnk", TRUE);
7386     delete_pf("msitest", FALSE);
7387     delete_test_files();
7388 }
7389
7390 static void test_envvar(void)
7391 {
7392     UINT r;
7393     HKEY env;
7394     LONG res;
7395     DWORD type, size;
7396     char buffer[16];
7397     UINT i;
7398
7399     if (on_win9x)
7400     {
7401         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
7402         return;
7403     }
7404
7405     create_test_files();
7406     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
7407
7408     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
7409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7410
7411     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
7412     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7413
7414     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
7415     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7416
7417     r = MsiInstallProductA(msifile, NULL);
7418     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7419
7420     type = REG_NONE;
7421     size = sizeof(buffer);
7422     buffer[0] = 0;
7423     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
7424     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7425     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7426     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7427
7428     res = RegDeleteValueA(env, "MSITESTVAR1");
7429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7430
7431     type = REG_NONE;
7432     size = sizeof(buffer);
7433     buffer[0] = 0;
7434     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
7435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7436     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7437     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7438
7439     res = RegDeleteValueA(env, "MSITESTVAR2");
7440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7441
7442     res = RegDeleteValueA(env, "MSITESTVAR3");
7443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7444
7445     res = RegDeleteValueA(env, "MSITESTVAR4");
7446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7447
7448     res = RegDeleteValueA(env, "MSITESTVAR5");
7449     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7450
7451     res = RegDeleteValueA(env, "MSITESTVAR6");
7452     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7453
7454     res = RegDeleteValueA(env, "MSITESTVAR7");
7455     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7456
7457     res = RegDeleteValueA(env, "MSITESTVAR8");
7458     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7459
7460     res = RegDeleteValueA(env, "MSITESTVAR9");
7461     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7462
7463     res = RegDeleteValueA(env, "MSITESTVAR10");
7464     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7465
7466     i = 11;
7467     while (environment_dat_results[(i-11)]) {
7468         char name[20];
7469         sprintf(name, "MSITESTVAR%d", i);
7470
7471         type = REG_NONE;
7472         size = sizeof(buffer);
7473         buffer[0] = 0;
7474         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
7475         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7476         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
7477         ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n",
7478            i, environment_dat_results[(i-11)], buffer);
7479
7480         res = RegDeleteValueA(env, name);
7481         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7482         i++;
7483     }
7484
7485
7486     RegCloseKey(env);
7487     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7488     delete_pf("msitest\\cabout\\new", FALSE);
7489     delete_pf("msitest\\cabout\\four.txt", TRUE);
7490     delete_pf("msitest\\cabout", FALSE);
7491     delete_pf("msitest\\changed\\three.txt", TRUE);
7492     delete_pf("msitest\\changed", FALSE);
7493     delete_pf("msitest\\first\\two.txt", TRUE);
7494     delete_pf("msitest\\first", FALSE);
7495     delete_pf("msitest\\filename", TRUE);
7496     delete_pf("msitest\\one.txt", TRUE);
7497     delete_pf("msitest\\service.exe", TRUE);
7498     delete_pf("msitest", FALSE);
7499     delete_test_files();
7500 }
7501
7502 static void test_preselected(void)
7503 {
7504     UINT r;
7505
7506     create_test_files();
7507     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
7508
7509     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
7510     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7511
7512     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
7513     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
7514     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
7515     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
7516     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
7517     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
7518     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
7519     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
7520     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
7521     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7522     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
7523     ok(delete_pf("msitest", FALSE), "File not installed\n");
7524
7525     r = MsiInstallProductA(msifile, NULL);
7526     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7527
7528     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7529     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7530     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7531     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7532     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7533     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7534     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7535     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7536     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7537     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7538     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7539     ok(delete_pf("msitest", FALSE), "File not installed\n");
7540     delete_test_files();
7541 }
7542
7543 static void test_installed_prop(void)
7544 {
7545     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
7546     UINT r;
7547
7548     create_test_files();
7549     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
7550
7551     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7552
7553     r = MsiInstallProductA(msifile, "FULL=1");
7554     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7555
7556     r = MsiInstallProductA(msifile, "FULL=1");
7557     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7558
7559     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
7560     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7561
7562     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7563     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7564     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7565     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7566     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7567     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7568     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7569     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7570     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7571     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7572     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7573     ok(delete_pf("msitest", FALSE), "File not installed\n");
7574
7575     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7577
7578     delete_test_files();
7579 }
7580
7581 static void test_allusers_prop(void)
7582 {
7583     UINT r;
7584
7585     create_test_files();
7586     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
7587
7588     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7589
7590     /* ALLUSERS property unset */
7591     r = MsiInstallProductA(msifile, "FULL=1");
7592     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7593
7594     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7595     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7596     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7597     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7598     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7599     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7600     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7601     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7602     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7603     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7604     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7605     ok(delete_pf("msitest", FALSE), "File not installed\n");
7606
7607     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7609
7610     delete_test_files();
7611
7612     create_test_files();
7613     create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
7614
7615     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7616
7617     /* ALLUSERS property set to 1 */
7618     r = MsiInstallProductA(msifile, "FULL=1");
7619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7620
7621     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7622     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7623     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7624     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7625     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7626     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7627     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7628     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7629     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7630     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7631     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7632     ok(delete_pf("msitest", FALSE), "File not installed\n");
7633
7634     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7636
7637     delete_test_files();
7638
7639     create_test_files();
7640     create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
7641
7642     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7643
7644     /* ALLUSERS property set to 2 */
7645     r = MsiInstallProductA(msifile, "FULL=1");
7646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7647
7648     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7649     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7650     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7651     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7652     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7653     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7654     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7655     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7656     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7657     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7658     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7659     ok(delete_pf("msitest", FALSE), "File not installed\n");
7660
7661     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7663
7664     delete_test_files();
7665
7666     create_test_files();
7667     create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
7668
7669     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7670
7671     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
7672     r = MsiInstallProductA(msifile, "FULL=1");
7673     if (r == ERROR_SUCCESS)
7674     {
7675         /* Win9x/WinMe */
7676         win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n");
7677
7678         ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7679         ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7680         ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7681         ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7682         ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7683         ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7684         ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7685         ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7686         ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7687         ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7688         ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7689         ok(delete_pf("msitest", FALSE), "File not installed\n");
7690
7691         r = MsiInstallProductA(msifile, "REMOVE=ALL");
7692         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7693
7694         delete_test_files();
7695     }
7696     else
7697         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7698 }
7699
7700 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
7701 static char rename_ops[]      = "PendingFileRenameOperations";
7702
7703 static void process_pending_renames(HKEY hkey)
7704 {
7705     char *buf, *src, *dst, *buf2, *buf2ptr;
7706     DWORD size, buf2len = 0;
7707     LONG ret;
7708     BOOL found = FALSE;
7709
7710     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
7711     buf = HeapAlloc(GetProcessHeap(), 0, size);
7712     buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7713     buf[0] = 0;
7714
7715     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
7716     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
7717
7718     for (src = buf; *src; src = dst + strlen(dst) + 1)
7719     {
7720         DWORD flags = MOVEFILE_COPY_ALLOWED;
7721
7722         dst = src + strlen(src) + 1;
7723
7724         if (!strstr(src, "msitest"))
7725         {
7726             lstrcpyA(buf2ptr, src);
7727             buf2len += strlen(src) + 1;
7728             buf2ptr += strlen(src) + 1;
7729             if (*dst)
7730             {
7731                 lstrcpyA(buf2ptr, dst);
7732                 buf2ptr += strlen(dst) + 1;
7733                 buf2len += strlen(dst) + 1;
7734             }
7735             buf2ptr++;
7736             buf2len++;
7737             continue;
7738         }
7739
7740         found = TRUE;
7741
7742         if (*dst == '!')
7743         {
7744             flags |= MOVEFILE_REPLACE_EXISTING;
7745             dst++;
7746         }
7747         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
7748         if (*dst)
7749         {
7750             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
7751             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
7752         }
7753         else
7754             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
7755     }
7756
7757     ok(found, "Expected a 'msitest' entry\n");
7758
7759     if (*buf2)
7760     {
7761         buf2len++;
7762         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len);
7763     }
7764     else
7765         RegDeleteValueA(hkey, rename_ops);
7766
7767     HeapFree(GetProcessHeap(), 0, buf);
7768     HeapFree(GetProcessHeap(), 0, buf2);
7769 }
7770
7771 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
7772 {
7773     DWORD len, data_len = strlen(data);
7774     HANDLE handle;
7775     char buf[128];
7776
7777     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7778     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
7779
7780     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
7781     {
7782         CloseHandle(handle);
7783         return !memcmp(buf, data, data_len);
7784     }
7785     CloseHandle(handle);
7786     return FALSE;
7787 }
7788
7789 static void test_file_in_use(void)
7790 {
7791     UINT r;
7792     HANDLE file;
7793     HKEY hkey;
7794     char path[MAX_PATH];
7795
7796     if (on_win9x)
7797     {
7798         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
7799         return;
7800     }
7801
7802     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
7803
7804     CreateDirectoryA("msitest", NULL);
7805     create_file("msitest\\maximus", 500);
7806     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
7807
7808     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7809
7810     lstrcpy(path, PROG_FILES_DIR);
7811     lstrcat(path, "\\msitest");
7812     CreateDirectoryA(path, NULL);
7813
7814     lstrcat(path, "\\maximus");
7815     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
7816
7817     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
7818     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
7819     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
7820     CloseHandle(file);
7821     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
7822
7823     process_pending_renames(hkey);
7824     RegCloseKey(hkey);
7825
7826     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
7827     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
7828     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
7829
7830     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7832
7833     delete_test_files();
7834 }
7835
7836 static void test_file_in_use_cab(void)
7837 {
7838     UINT r;
7839     HANDLE file;
7840     HKEY hkey;
7841     char path[MAX_PATH];
7842
7843     if (on_win9x)
7844     {
7845         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
7846         return;
7847     }
7848
7849     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
7850
7851     CreateDirectoryA("msitest", NULL);
7852     create_file("maximus", 500);
7853     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
7854     DeleteFile("maximus");
7855
7856     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
7857
7858     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7859
7860     lstrcpy(path, PROG_FILES_DIR);
7861     lstrcat(path, "\\msitest");
7862     CreateDirectoryA(path, NULL);
7863
7864     lstrcat(path, "\\maximus");
7865     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
7866
7867     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
7868     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
7869     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
7870     CloseHandle(file);
7871     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
7872
7873     process_pending_renames(hkey);
7874     RegCloseKey(hkey);
7875
7876     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
7877     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
7878     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
7879
7880     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7881     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7882
7883     delete_cab_files();
7884     delete_test_files();
7885 }
7886
7887 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
7888 {
7889     return IDOK;
7890 }
7891
7892 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
7893 {
7894     return IDOK;
7895 }
7896
7897 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
7898 {
7899     return IDOK;
7900 }
7901
7902 static void test_MsiSetExternalUI(void)
7903 {
7904     INSTALLUI_HANDLERA ret_a;
7905     INSTALLUI_HANDLERW ret_w;
7906     INSTALLUI_HANDLER_RECORD prev;
7907     UINT error;
7908
7909     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
7910     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7911
7912     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
7913     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
7914
7915     /* Not present before Installer 3.1 */
7916     if (!pMsiSetExternalUIRecord) {
7917         win_skip("MsiSetExternalUIRecord is not available\n");
7918         return;
7919     }
7920
7921     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
7922     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7923     ok(prev == NULL, "expected NULL, got %p\n", prev);
7924
7925     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7926     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
7927     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7928     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
7929
7930     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
7931     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7932
7933     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
7934     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
7935
7936     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
7937     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7938
7939     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
7940     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7941
7942     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7943     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
7944     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7945     ok(prev == NULL, "expected NULL, got %p\n", prev);
7946
7947     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
7948     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7949
7950     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
7951     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7952
7953     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7954     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
7955     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7956     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
7957
7958     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
7959     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7960
7961     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
7962     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7963 }
7964
7965 static void test_feature_override(void)
7966 {
7967     UINT r;
7968
7969     create_test_files();
7970     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
7971
7972     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
7973     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7974
7975     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
7976     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
7977     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
7978     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
7979     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
7980     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
7981     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
7982     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
7983     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
7984     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7985     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
7986     ok(delete_pf("msitest", FALSE), "File not installed\n");
7987
7988     delete_test_files();
7989 }
7990
7991 static void test_create_folder(void)
7992 {
7993     UINT r;
7994
7995     create_test_files();
7996     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
7997
7998     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7999
8000     r = MsiInstallProductA(msifile, NULL);
8001     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8002
8003     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8004     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8005     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8006     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8007     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8008     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8009     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8010     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8011     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8012     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8013     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8014     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8015
8016     r = MsiInstallProductA(msifile, "LOCAL=Two");
8017     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8018
8019     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8020     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8021     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8022     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8023     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8024     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8025     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8026     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8027     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8028     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8029     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8030     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8031
8032     delete_test_files();
8033 }
8034
8035 static void test_remove_folder(void)
8036 {
8037     UINT r;
8038
8039     create_test_files();
8040     create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table));
8041
8042     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8043
8044     r = MsiInstallProductA(msifile, NULL);
8045     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8046
8047     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8048     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8049     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8050     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8051     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8052     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8053     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8054     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8055     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8056     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8057     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8058     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8059
8060     r = MsiInstallProductA(msifile, "LOCAL=Two");
8061     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8062
8063     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8064     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8065     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8066     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8067     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8068     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8069     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8070     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8071     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8072     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8073     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8074     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8075
8076     delete_test_files();
8077 }
8078
8079 static void test_start_services(void)
8080 {
8081     UINT r;
8082     SC_HANDLE scm, service;
8083     BOOL ret;
8084     DWORD error = ERROR_SUCCESS;
8085
8086     if (on_win9x)
8087     {
8088         win_skip("Services are not implemented on Win9x and WinMe\n");
8089         return;
8090     }
8091     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8092     ok(scm != NULL, "Failed to open the SC Manager\n");
8093     if (!scm) return;
8094
8095     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8096     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
8097     {
8098         win_skip("The 'Spooler' service does not exist\n");
8099         CloseServiceHandle(scm);
8100         return;
8101     }
8102     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
8103     if (!service) {
8104         CloseServiceHandle(scm);
8105         return;
8106     }
8107
8108     ret = StartService(service, 0, NULL);
8109     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
8110     {
8111         skip("Terminal service not available, skipping test\n");
8112         CloseServiceHandle(service);
8113         CloseServiceHandle(scm);
8114         return;
8115     }
8116
8117     CloseServiceHandle(service);
8118     CloseServiceHandle(scm);
8119
8120     create_test_files();
8121     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
8122
8123     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8124
8125     r = MsiInstallProductA(msifile, NULL);
8126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8127
8128     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8129     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8130     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8131     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8132     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8133     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8134     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8135     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8136     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8137     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8138     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8139     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8140
8141     delete_test_files();
8142
8143     if (error == ERROR_SUCCESS)
8144     {
8145         SERVICE_STATUS status;
8146
8147         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8148         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8149
8150         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
8151         ok(ret, "ControlService failed %u\n", GetLastError());
8152
8153         CloseServiceHandle(service);
8154         CloseServiceHandle(scm);
8155     }
8156 }
8157
8158 static void test_delete_services(void)
8159 {
8160     UINT r;
8161
8162     create_test_files();
8163     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
8164
8165     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8166
8167     r = MsiInstallProductA(msifile, NULL);
8168     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8169
8170     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8171     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8172     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8173     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8174     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8175     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8176     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8177     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8178     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8179     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8180     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8181     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8182
8183     delete_test_files();
8184 }
8185
8186 static void test_self_registration(void)
8187 {
8188     UINT r;
8189
8190     create_test_files();
8191     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
8192
8193     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8194
8195     r = MsiInstallProductA(msifile, NULL);
8196     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8197
8198     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8199     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8200     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8201     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8202     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8203     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8204     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8205     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8206     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8207     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8208     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8209     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8210
8211     delete_test_files();
8212 }
8213
8214 static void test_register_font(void)
8215 {
8216     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
8217     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
8218     LONG ret;
8219     HKEY key;
8220     UINT r;
8221
8222     create_test_files();
8223     create_file("msitest\\font.ttf", 1000);
8224     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
8225
8226     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8227
8228     r = MsiInstallProductA(msifile, NULL);
8229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8230
8231     ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key);
8232     if (ret)
8233         RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key);
8234
8235     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8236     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8237
8238     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8240
8241     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8242
8243     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8244     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8245
8246     RegDeleteValueA(key, "msi test font");
8247     RegCloseKey(key);
8248     delete_test_files();
8249 }
8250
8251 static void test_validate_product_id(void)
8252 {
8253     UINT r;
8254
8255     create_test_files();
8256     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
8257
8258     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8259
8260     r = MsiInstallProductA(msifile, NULL);
8261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8262
8263     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
8264     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8265
8266     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
8267     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8268
8269     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
8270     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8271
8272     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8273     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8274     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8275     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8276     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8277     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8278     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8279     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8280     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8281     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8282     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8283     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8284
8285     delete_test_files();
8286 }
8287
8288 static void test_install_remove_odbc(void)
8289 {
8290     UINT r;
8291
8292     create_test_files();
8293     create_file("msitest\\ODBCdriver.dll", 1000);
8294     create_file("msitest\\ODBCdriver2.dll", 1000);
8295     create_file("msitest\\ODBCtranslator.dll", 1000);
8296     create_file("msitest\\ODBCtranslator2.dll", 1000);
8297     create_file("msitest\\ODBCsetup.dll", 1000);
8298     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
8299
8300     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8301
8302     r = MsiInstallProductA(msifile, NULL);
8303     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8304
8305     ok(delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not created\n");
8306     ok(delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not created\n");
8307     ok(delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not created\n");
8308     ok(delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not created\n");
8309     ok(delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not created\n");
8310     ok(delete_pf("msitest", FALSE), "directory not created\n");
8311
8312     delete_test_files();
8313 }
8314
8315 static void test_register_typelib(void)
8316 {
8317     UINT r;
8318
8319     create_test_files();
8320     create_file("msitest\\typelib.dll", 1000);
8321     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
8322
8323     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8324
8325     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
8326     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8327
8328     r = MsiInstallProductA(msifile, NULL);
8329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8330
8331     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8332     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8333
8334     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
8335     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8336
8337     delete_test_files();
8338 }
8339
8340 static void test_create_remove_shortcut(void)
8341 {
8342     UINT r;
8343
8344     create_test_files();
8345     create_file("msitest\\target.txt", 1000);
8346     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
8347
8348     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8349
8350     r = MsiInstallProductA(msifile, NULL);
8351     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8352
8353     ok(pf_exists("msitest\\target.txt"), "file not created\n");
8354     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
8355
8356     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8358
8359     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
8360     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
8361     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8362
8363     delete_test_files();
8364 }
8365
8366 static void test_publish_components(void)
8367 {
8368     static char keypath[] =
8369         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
8370
8371     UINT r;
8372     LONG res;
8373     HKEY key;
8374
8375     create_test_files();
8376     create_file("msitest\\english.txt", 1000);
8377     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
8378
8379     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8380
8381     r = MsiInstallProductA(msifile, NULL);
8382     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8383
8384     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8385     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
8386
8387     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
8388     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
8389     RegCloseKey(key);
8390
8391     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8392     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8393
8394     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8395     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
8396
8397     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
8398     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8399     delete_test_files();
8400 }
8401
8402 static void test_remove_duplicate_files(void)
8403 {
8404     UINT r;
8405
8406     create_test_files();
8407     create_file("msitest\\original.txt", 1000);
8408     create_file("msitest\\original2.txt", 1000);
8409     create_file("msitest\\original3.txt", 1000);
8410     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
8411
8412     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8413
8414     r = MsiInstallProductA(msifile, NULL);
8415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8416
8417     ok(pf_exists("msitest\\original.txt"), "file not created\n");
8418     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
8419     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
8420     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
8421     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
8422
8423     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8425
8426     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
8427     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
8428     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
8429     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
8430     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
8431     ok(delete_pf("msitest", FALSE), "directory removed\n");
8432     delete_test_files();
8433 }
8434
8435 static void test_remove_registry_values(void)
8436 {
8437     UINT r;
8438     LONG res;
8439     HKEY key;
8440
8441     create_test_files();
8442     create_file("msitest\\registry.txt", 1000);
8443     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
8444
8445     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8446
8447     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8448     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
8449     RegCloseKey(key);
8450
8451     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8452     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
8453     RegCloseKey(key);
8454
8455     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8456     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8457     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
8458     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8459     RegCloseKey(key);
8460
8461     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8462     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8463     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8464     RegCloseKey(key);
8465
8466     r = MsiInstallProductA(msifile, NULL);
8467     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8468
8469     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8470     ok(res == ERROR_SUCCESS, "key removed\n");
8471     RegCloseKey(key);
8472
8473     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8474     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8475
8476     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8478     RegCloseKey(key);
8479
8480     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8482
8483     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8484     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8485
8486     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8487     ok(res == ERROR_SUCCESS, "key removed\n");
8488     RegCloseKey(key);
8489
8490     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8491     ok(res == ERROR_SUCCESS, "key removed\n");
8492     RegCloseKey(key);
8493
8494     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8495     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8496
8497     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA");
8498     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2");
8499     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine");
8500
8501     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
8502     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8503     delete_test_files();
8504 }
8505
8506 START_TEST(install)
8507 {
8508     DWORD len;
8509     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
8510     STATEMGRSTATUS status;
8511     BOOL ret = FALSE;
8512
8513     init_functionpointers();
8514
8515     on_win9x = check_win9x();
8516
8517     GetCurrentDirectoryA(MAX_PATH, prev_path);
8518     GetTempPath(MAX_PATH, temp_path);
8519     SetCurrentDirectoryA(temp_path);
8520
8521     lstrcpyA(CURR_DIR, temp_path);
8522     len = lstrlenA(CURR_DIR);
8523
8524     if(len && (CURR_DIR[len - 1] == '\\'))
8525         CURR_DIR[len - 1] = 0;
8526
8527     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
8528
8529     /* Create a restore point ourselves so we circumvent the multitude of restore points
8530      * that would have been created by all the installation and removal tests.
8531      */
8532     if (pSRSetRestorePointA)
8533     {
8534         memset(&status, 0, sizeof(status));
8535         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
8536     }
8537
8538     /* Create only one log file and don't append. We have to pass something
8539      * for the log mode for this to work. The logfile needs to have an absolute
8540      * path otherwise we still end up with some extra logfiles as some tests
8541      * change the current directory.
8542      */
8543     lstrcpyA(log_file, temp_path);
8544     lstrcatA(log_file, "\\msitest.log");
8545     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
8546
8547     test_MsiInstallProduct();
8548     test_MsiSetComponentState();
8549     test_packagecoltypes();
8550     test_continuouscabs();
8551     test_caborder();
8552     test_mixedmedia();
8553     test_samesequence();
8554     test_uiLevelFlags();
8555     test_readonlyfile();
8556     test_readonlyfile_cab();
8557     test_setdirproperty();
8558     test_cabisextracted();
8559     test_concurrentinstall();
8560     test_setpropertyfolder();
8561     test_publish_registerproduct();
8562     test_publish_publishproduct();
8563     test_publish_publishfeatures();
8564     test_publish_registeruser();
8565     test_publish_processcomponents();
8566     test_publish();
8567     test_publishsourcelist();
8568     test_transformprop();
8569     test_currentworkingdir();
8570     test_admin();
8571     test_adminprops();
8572     test_removefiles();
8573     test_movefiles();
8574     test_missingcab();
8575     test_duplicatefiles();
8576     test_writeregistryvalues();
8577     test_sourcefolder();
8578     test_customaction51();
8579     test_installstate();
8580     test_sourcepath();
8581     test_MsiConfigureProductEx();
8582     test_missingcomponent();
8583     test_sourcedirprop();
8584     test_adminimage();
8585     test_propcase();
8586     test_int_widths();
8587     test_shortcut();
8588     test_envvar();
8589     test_lastusedsource();
8590     test_preselected();
8591     test_installed_prop();
8592     test_file_in_use();
8593     test_file_in_use_cab();
8594     test_MsiSetExternalUI();
8595     test_allusers_prop();
8596     test_feature_override();
8597     test_create_folder();
8598     test_remove_folder();
8599     test_start_services();
8600     test_delete_services();
8601     test_self_registration();
8602     test_register_font();
8603     test_validate_product_id();
8604     test_install_remove_odbc();
8605     test_register_typelib();
8606     test_create_remove_shortcut();
8607     test_publish_components();
8608     test_remove_duplicate_files();
8609     test_remove_registry_values();
8610
8611     DeleteFileA(log_file);
8612
8613     if (pSRSetRestorePointA && ret)
8614     {
8615         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
8616         if (ret)
8617             remove_restore_point(status.llSequenceNumber);
8618     }
8619     FreeLibrary(hsrclient);
8620
8621     SetCurrentDirectoryA(prev_path);
8622 }