msi: Add tests for removing registry values.
[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 deleted\n");
5143     todo_wine
5144     {
5145         ok(!pf_exists("msitest"), "File deleted\n");
5146     }
5147
5148     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5149     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5150
5151     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5152     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5153
5154     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5155     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5156
5157     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5158                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5159     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5160     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5161
5162     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5163     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5164
5165     /* complete install */
5166     r = MsiInstallProductA(msifile, "FULL=1");
5167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5168     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5169     ok(pf_exists("msitest"), "File not installed\n");
5170
5171     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5172     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5173
5174     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5175     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5176
5177     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5178     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5179
5180     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5181                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5183     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5184
5185     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5187
5188     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5189     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5190     CHECK_REG_STR(prodkey, "InstallDate", date);
5191     CHECK_REG_STR(prodkey, "InstallSource", temp);
5192     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5193     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5194     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5195     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5196     CHECK_REG_STR(prodkey, "Comments", NULL);
5197     CHECK_REG_STR(prodkey, "Contact", NULL);
5198     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5199     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5200     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5201     CHECK_REG_STR(prodkey, "Readme", NULL);
5202     CHECK_REG_STR(prodkey, "Size", NULL);
5203     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5204     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5205     CHECK_REG_DWORD(prodkey, "Language", 1033);
5206     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5207     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5208     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5209     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5210     todo_wine
5211     {
5212         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5213     }
5214
5215     RegCloseKey(prodkey);
5216
5217     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
5218     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
5219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5220     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
5221     ok(pf_exists("msitest"), "File deleted\n");
5222
5223     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5224     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5225
5226     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5227     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5228
5229     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5230     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5231
5232     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5233                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5235     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5236
5237     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5239
5240     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5241     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5242     CHECK_REG_STR(prodkey, "InstallDate", date);
5243     CHECK_REG_STR(prodkey, "InstallSource", temp);
5244     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5245     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5246     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5247     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5248     CHECK_REG_STR(prodkey, "Comments", NULL);
5249     CHECK_REG_STR(prodkey, "Contact", NULL);
5250     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5251     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5252     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5253     CHECK_REG_STR(prodkey, "Readme", NULL);
5254     CHECK_REG_STR(prodkey, "Size", NULL);
5255     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5256     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5257     CHECK_REG_DWORD(prodkey, "Language", 1033);
5258     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5259     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5260     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5261     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5262     todo_wine
5263     {
5264         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5265     }
5266
5267     RegCloseKey(prodkey);
5268
5269     /* complete install */
5270     r = MsiInstallProductA(msifile, "FULL=1");
5271     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5272     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5273     ok(pf_exists("msitest"), "File not installed\n");
5274
5275     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5276     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5277
5278     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5279     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5280
5281     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5282     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5283
5284     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5285                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5287     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5288
5289     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5291
5292     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5293     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5294     CHECK_REG_STR(prodkey, "InstallDate", date);
5295     CHECK_REG_STR(prodkey, "InstallSource", temp);
5296     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5297     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5298     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5299     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5300     CHECK_REG_STR(prodkey, "Comments", NULL);
5301     CHECK_REG_STR(prodkey, "Contact", NULL);
5302     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5303     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5304     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5305     CHECK_REG_STR(prodkey, "Readme", NULL);
5306     CHECK_REG_STR(prodkey, "Size", NULL);
5307     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5308     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5309     CHECK_REG_DWORD(prodkey, "Language", 1033);
5310     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5311     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5312     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5313     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5314     todo_wine
5315     {
5316         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
5317     }
5318
5319     RegCloseKey(prodkey);
5320
5321     /* UnpublishFeatures, both features removed */
5322     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
5323     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5324     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5325     todo_wine
5326     {
5327         ok(!pf_exists("msitest"), "File not deleted\n");
5328     }
5329
5330     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5331     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5332
5333     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5334     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5335
5336     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5337     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5338
5339     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5340                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5341     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5342     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5343
5344     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5345     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5346
5347     /* complete install */
5348     r = MsiInstallProductA(msifile, "FULL=1");
5349     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5350     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5351     ok(pf_exists("msitest"), "File not installed\n");
5352
5353     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5354     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5355
5356     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5357     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5358
5359     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5360     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5361
5362     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5363                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5364     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5365     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5366
5367     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5369
5370     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5371     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5372     CHECK_REG_STR(prodkey, "InstallDate", date);
5373     CHECK_REG_STR(prodkey, "InstallSource", temp);
5374     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5375     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5376     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5377     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5378     CHECK_REG_STR(prodkey, "Comments", NULL);
5379     CHECK_REG_STR(prodkey, "Contact", NULL);
5380     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5381     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5382     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5383     CHECK_REG_STR(prodkey, "Readme", NULL);
5384     CHECK_REG_STR(prodkey, "Size", NULL);
5385     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5386     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5387     CHECK_REG_DWORD(prodkey, "Language", 1033);
5388     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5389     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5390     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5391     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5392     todo_wine
5393     {
5394         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5395     }
5396
5397     RegCloseKey(prodkey);
5398
5399     /* complete uninstall */
5400     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5402     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5403     todo_wine
5404     {
5405         ok(!pf_exists("msitest"), "File not deleted\n");
5406     }
5407
5408     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5409     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5410
5411     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5412     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5413
5414     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5415     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5416
5417     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5418                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5419     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5420     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5421
5422     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5423     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5424
5425     /* make sure 'Program Files\msitest' is removed */
5426     delete_pfmsitest_files();
5427
5428     RegCloseKey(uninstall);
5429     DeleteFile(msifile);
5430     DeleteFile("msitest\\maximus");
5431     RemoveDirectory("msitest");
5432 }
5433
5434 static void test_publishsourcelist(void)
5435 {
5436     UINT r;
5437     DWORD size;
5438     CHAR value[MAX_PATH];
5439     CHAR path[MAX_PATH];
5440     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5441
5442     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
5443     {
5444         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
5445         return;
5446     }
5447
5448     CreateDirectoryA("msitest", NULL);
5449     create_file("msitest\\maximus", 500);
5450
5451     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5452
5453     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5454
5455     r = MsiInstallProductA(msifile, NULL);
5456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5457     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5458     ok(pf_exists("msitest"), "File not installed\n");
5459
5460     /* nothing published */
5461     size = MAX_PATH;
5462     lstrcpyA(value, "aaa");
5463     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5464                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5465     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5466     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5467     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5468
5469     size = MAX_PATH;
5470     lstrcpyA(value, "aaa");
5471     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5472                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5473     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5474     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5475     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5476
5477     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
5478     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5479     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5480     ok(pf_exists("msitest"), "File not installed\n");
5481
5482     /* after RegisterProduct */
5483     size = MAX_PATH;
5484     lstrcpyA(value, "aaa");
5485     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5486                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5487     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5488     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5489     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5490
5491     size = MAX_PATH;
5492     lstrcpyA(value, "aaa");
5493     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5494                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5495     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5496     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5497     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5498
5499     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5501     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5502     ok(pf_exists("msitest"), "File not installed\n");
5503
5504     /* after ProcessComponents */
5505     size = MAX_PATH;
5506     lstrcpyA(value, "aaa");
5507     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5508                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5509     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5510     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5511     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5512
5513     size = MAX_PATH;
5514     lstrcpyA(value, "aaa");
5515     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5516                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5517     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5518     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5519     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5520
5521     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
5522     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5523     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5524     ok(pf_exists("msitest"), "File not installed\n");
5525
5526     /* after PublishFeatures */
5527     size = MAX_PATH;
5528     lstrcpyA(value, "aaa");
5529     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5530                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5531     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5532     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5533     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5534
5535     size = MAX_PATH;
5536     lstrcpyA(value, "aaa");
5537     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5538                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5539     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5540     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5541     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5542
5543     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
5544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5545     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5546     ok(pf_exists("msitest"), "File not installed\n");
5547
5548     /* after PublishProduct */
5549     size = MAX_PATH;
5550     lstrcpyA(value, "aaa");
5551     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5552                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5553     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5554     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
5555     ok(size == 11, "Expected 11, got %d\n", size);
5556
5557     size = MAX_PATH;
5558     lstrcpyA(value, "aaa");
5559     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5560                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
5561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5562     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5563     ok(size == 0, "Expected 0, got %d\n", size);
5564
5565     size = MAX_PATH;
5566     lstrcpyA(value, "aaa");
5567     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5568                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
5569     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5570     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5571     ok(size == 0, "Expected 0, got %d\n", size);
5572
5573     lstrcpyA(path, CURR_DIR);
5574     lstrcatA(path, "\\");
5575
5576     size = MAX_PATH;
5577     lstrcpyA(value, "aaa");
5578     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5579                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
5580     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5581     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5582     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5583
5584     size = MAX_PATH;
5585     lstrcpyA(value, "aaa");
5586     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5587                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
5588     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5589     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
5590     ok(size == 1, "Expected 1, got %d\n", size);
5591
5592     size = MAX_PATH;
5593     lstrcpyA(value, "aaa");
5594     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5595                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5596     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5597     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5598     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5599
5600     size = MAX_PATH;
5601     lstrcpyA(value, "aaa");
5602     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5603                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
5604     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5605     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5606     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5607
5608     size = MAX_PATH;
5609     lstrcpyA(value, "aaa");
5610     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5611                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
5612     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5613     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5614     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5615
5616     /* complete uninstall */
5617     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5619     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5620     todo_wine
5621     {
5622         ok(!pf_exists("msitest"), "File not deleted\n");
5623     }
5624
5625     /* make sure 'Program Files\msitest' is removed */
5626     delete_pfmsitest_files();
5627
5628     DeleteFile(msifile);
5629     DeleteFile("msitest\\maximus");
5630     RemoveDirectory("msitest");
5631 }
5632
5633 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
5634 {
5635     MSIHANDLE hview = 0;
5636     UINT r;
5637
5638     r = MsiDatabaseOpenView(hdb, query, &hview);
5639     if(r != ERROR_SUCCESS)
5640         return r;
5641
5642     r = MsiViewExecute(hview, hrec);
5643     if(r == ERROR_SUCCESS)
5644         r = MsiViewClose(hview);
5645     MsiCloseHandle(hview);
5646     return r;
5647 }
5648
5649 static void set_transform_summary_info(void)
5650 {
5651     UINT r;
5652     MSIHANDLE suminfo = 0;
5653
5654     /* build summary info */
5655     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
5656     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
5657
5658     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
5659     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5660
5661     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
5662                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5663                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5664                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
5665     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
5666
5667     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
5668     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5669
5670     r = MsiSummaryInfoPersist(suminfo);
5671     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
5672
5673     r = MsiCloseHandle(suminfo);
5674     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
5675 }
5676
5677 static void generate_transform(void)
5678 {
5679     MSIHANDLE hdb1, hdb2;
5680     LPCSTR query;
5681     UINT r;
5682
5683     /* start with two identical databases */
5684     CopyFile(msifile, msifile2, FALSE);
5685
5686     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
5687     ok(r == ERROR_SUCCESS , "Failed to create database\n");
5688
5689     r = MsiDatabaseCommit(hdb1);
5690     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
5691
5692     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
5693     ok(r == ERROR_SUCCESS , "Failed to create database\n");
5694
5695     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
5696     r = run_query(hdb1, 0, query);
5697     ok(r == ERROR_SUCCESS, "failed to add property\n");
5698
5699     /* database needs to be committed */
5700     MsiDatabaseCommit(hdb1);
5701
5702     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
5703     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
5704
5705 #if 0  /* not implemented in wine yet */
5706     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
5707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5708 #endif
5709
5710     MsiCloseHandle(hdb1);
5711     MsiCloseHandle(hdb2);
5712 }
5713
5714 /* data for generating a transform */
5715
5716 /* tables transform names - encoded as they would be in an msi database file */
5717 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
5718 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
5719 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
5720
5721 /* data in each table */
5722 static const char data1[] = /* _StringData */
5723     "propval";  /* all the strings squashed together */
5724
5725 static const WCHAR data2[] = { /* _StringPool */
5726 /*  len, refs */
5727     0,   0,    /* string 0 ''     */
5728     4,   1,    /* string 1 'prop' */
5729     3,   1,    /* string 2 'val'  */
5730 };
5731
5732 static const WCHAR data3[] = { /* Property */
5733     0x0201, 0x0001, 0x0002,
5734 };
5735
5736 static const struct {
5737     LPCWSTR name;
5738     const void *data;
5739     DWORD size;
5740 } table_transform_data[] =
5741 {
5742     { name1, data1, sizeof data1 - 1 },
5743     { name2, data2, sizeof data2 },
5744     { name3, data3, sizeof data3 },
5745 };
5746
5747 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
5748
5749 static void generate_transform_manual(void)
5750 {
5751     IStorage *stg = NULL;
5752     IStream *stm;
5753     WCHAR name[0x20];
5754     HRESULT r;
5755     DWORD i, count;
5756     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
5757
5758     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
5759
5760     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
5761
5762     r = StgCreateDocfile(name, mode, 0, &stg);
5763     ok(r == S_OK, "failed to create storage\n");
5764     if (!stg)
5765         return;
5766
5767     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
5768     ok(r == S_OK, "failed to set storage type\n");
5769
5770     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
5771     {
5772         r = IStorage_CreateStream(stg, table_transform_data[i].name,
5773                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
5774         if (FAILED(r))
5775         {
5776             ok(0, "failed to create stream %08x\n", r);
5777             continue;
5778         }
5779
5780         r = IStream_Write(stm, table_transform_data[i].data,
5781                           table_transform_data[i].size, &count);
5782         if (FAILED(r) || count != table_transform_data[i].size)
5783             ok(0, "failed to write stream\n");
5784         IStream_Release(stm);
5785     }
5786
5787     IStorage_Release(stg);
5788
5789     set_transform_summary_info();
5790 }
5791
5792 static void test_transformprop(void)
5793 {
5794     UINT r;
5795
5796     CreateDirectoryA("msitest", NULL);
5797     create_file("msitest\\augustus", 500);
5798
5799     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
5800
5801     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5802
5803     r = MsiInstallProductA(msifile, NULL);
5804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5805     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5806     ok(!delete_pf("msitest", FALSE), "File installed\n");
5807
5808     if (0)
5809         generate_transform();
5810     else
5811         generate_transform_manual();
5812
5813     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
5814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5815     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5816     ok(delete_pf("msitest", FALSE), "File not installed\n");
5817
5818     /* Delete the files in the temp (current) folder */
5819     DeleteFile(msifile);
5820     DeleteFile(msifile2);
5821     DeleteFile(mstfile);
5822     DeleteFile("msitest\\augustus");
5823     RemoveDirectory("msitest");
5824 }
5825
5826 static void test_currentworkingdir(void)
5827 {
5828     UINT r;
5829     CHAR drive[MAX_PATH], path[MAX_PATH];
5830     LPSTR ptr;
5831
5832     CreateDirectoryA("msitest", NULL);
5833     create_file("msitest\\augustus", 500);
5834
5835     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
5836
5837     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5838
5839     CreateDirectoryA("diffdir", NULL);
5840     SetCurrentDirectoryA("diffdir");
5841
5842     sprintf(path, "..\\%s", msifile);
5843     r = MsiInstallProductA(path, NULL);
5844     todo_wine
5845     {
5846         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
5847         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5848         ok(!delete_pf("msitest", FALSE), "File installed\n");
5849     }
5850
5851     sprintf(path, "%s\\%s", CURR_DIR, msifile);
5852     r = MsiInstallProductA(path, NULL);
5853     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5854     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5855     ok(delete_pf("msitest", FALSE), "File not installed\n");
5856
5857     lstrcpyA(drive, CURR_DIR);
5858     drive[2] = '\\';
5859     drive[3] = '\0';
5860     SetCurrentDirectoryA(drive);
5861
5862     lstrcpy(path, CURR_DIR);
5863     if (path[lstrlenA(path) - 1] != '\\')
5864         lstrcatA(path, "\\");
5865     lstrcatA(path, msifile);
5866     ptr = strchr(path, ':');
5867     ptr +=2;
5868
5869     r = MsiInstallProductA(ptr, NULL);
5870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5871     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5872     ok(delete_pf("msitest", FALSE), "File not installed\n");
5873
5874     SetCurrentDirectoryA(CURR_DIR);
5875
5876     DeleteFile(msifile);
5877     DeleteFile("msitest\\augustus");
5878     RemoveDirectory("msitest");
5879     RemoveDirectory("diffdir");
5880 }
5881
5882 static void set_admin_summary_info(const CHAR *name)
5883 {
5884     MSIHANDLE db, summary;
5885     UINT r;
5886
5887     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
5888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5889
5890     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
5891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5892
5893     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
5894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5895
5896     /* write the summary changes back to the stream */
5897     r = MsiSummaryInfoPersist(summary);
5898     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5899
5900     MsiCloseHandle(summary);
5901
5902     r = MsiDatabaseCommit(db);
5903     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5904
5905     MsiCloseHandle(db);
5906 }
5907
5908 static void test_admin(void)
5909 {
5910     UINT r;
5911
5912     CreateDirectoryA("msitest", NULL);
5913     create_file("msitest\\augustus", 500);
5914
5915     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
5916     set_admin_summary_info(msifile);
5917
5918     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5919
5920     r = MsiInstallProductA(msifile, NULL);
5921     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5922     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5923     ok(!delete_pf("msitest", FALSE), "File installed\n");
5924     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
5925     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
5926
5927     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
5928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5929     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5930     ok(!delete_pf("msitest", FALSE), "File installed\n");
5931     todo_wine
5932     {
5933         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
5934         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
5935     }
5936
5937     DeleteFile(msifile);
5938     DeleteFile("msitest\\augustus");
5939     RemoveDirectory("msitest");
5940 }
5941
5942 static void set_admin_property_stream(LPCSTR file)
5943 {
5944     IStorage *stg;
5945     IStream *stm;
5946     WCHAR fileW[MAX_PATH];
5947     HRESULT hr;
5948     DWORD count;
5949     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
5950
5951     /* AdminProperties */
5952     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
5953     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
5954         'M','y','P','r','o','p','=','4','2',0};
5955
5956     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
5957
5958     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
5959     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5960     if (!stg)
5961         return;
5962
5963     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
5964     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5965
5966     hr = IStream_Write(stm, data, sizeof(data), &count);
5967     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5968
5969     IStream_Release(stm);
5970     IStorage_Release(stg);
5971 }
5972
5973 static void test_adminprops(void)
5974 {
5975     UINT r;
5976
5977     CreateDirectoryA("msitest", NULL);
5978     create_file("msitest\\augustus", 500);
5979
5980     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
5981     set_admin_summary_info(msifile);
5982     set_admin_property_stream(msifile);
5983
5984     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5985
5986     r = MsiInstallProductA(msifile, NULL);
5987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5988     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5989     ok(delete_pf("msitest", FALSE), "File installed\n");
5990
5991     DeleteFile(msifile);
5992     DeleteFile("msitest\\augustus");
5993     RemoveDirectory("msitest");
5994 }
5995
5996 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
5997 {
5998     CHAR path[MAX_PATH];
5999
6000     lstrcpyA(path, PROG_FILES_DIR);
6001     lstrcatA(path, "\\");
6002     lstrcatA(path, file);
6003
6004     if (is_file)
6005         create_file_data(path, data, 500);
6006     else
6007         CreateDirectoryA(path, NULL);
6008 }
6009
6010 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
6011
6012 static void test_removefiles(void)
6013 {
6014     UINT r;
6015
6016     CreateDirectoryA("msitest", NULL);
6017     create_file("msitest\\hydrogen", 500);
6018     create_file("msitest\\helium", 500);
6019     create_file("msitest\\lithium", 500);
6020
6021     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
6022
6023     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6024
6025     r = MsiInstallProductA(msifile, NULL);
6026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6027     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6028     ok(!pf_exists("msitest\\helium"), "File installed\n");
6029     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6030     ok(pf_exists("msitest"), "File not installed\n");
6031
6032     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6034     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6035     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
6036     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6037     ok(delete_pf("msitest", FALSE), "File deleted\n");
6038
6039     create_pf("msitest", FALSE);
6040     create_pf("msitest\\hydrogen", TRUE);
6041     create_pf("msitest\\helium", TRUE);
6042     create_pf("msitest\\lithium", TRUE);
6043
6044     r = MsiInstallProductA(msifile, NULL);
6045     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6046     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6047     ok(pf_exists("msitest\\helium"), "File not installed\n");
6048     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6049     ok(pf_exists("msitest"), "File not installed\n");
6050
6051     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6052     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6053     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6054     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
6055     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6056     ok(delete_pf("msitest", FALSE), "File deleted\n");
6057
6058     create_pf("msitest", FALSE);
6059     create_pf("msitest\\furlong", TRUE);
6060     create_pf("msitest\\firkin", TRUE);
6061     create_pf("msitest\\fortnight", TRUE);
6062     create_pf("msitest\\becquerel", TRUE);
6063     create_pf("msitest\\dioptre", TRUE);
6064     create_pf("msitest\\attoparsec", TRUE);
6065     create_pf("msitest\\storeys", TRUE);
6066     create_pf("msitest\\block", TRUE);
6067     create_pf("msitest\\siriometer", TRUE);
6068     create_pf("msitest\\cabout", FALSE);
6069     create_pf("msitest\\cabout\\blocker", TRUE);
6070
6071     r = MsiInstallProductA(msifile, NULL);
6072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6073     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6074     ok(!pf_exists("msitest\\helium"), "File installed\n");
6075     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6076     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
6077     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
6078     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
6079     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
6080     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
6081     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
6082     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
6083     ok(!pf_exists("msitest\\block"), "File not deleted\n");
6084     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
6085     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
6086     ok(pf_exists("msitest"), "File not installed\n");
6087
6088     create_pf("msitest\\furlong", TRUE);
6089     create_pf("msitest\\firkin", TRUE);
6090     create_pf("msitest\\fortnight", TRUE);
6091     create_pf("msitest\\storeys", TRUE);
6092     create_pf("msitest\\block", TRUE);
6093     create_pf("msitest\\siriometer", TRUE);
6094
6095     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6096     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6097     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
6098     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
6099     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6100     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
6101     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
6102     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
6103     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
6104     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
6105     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
6106     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
6107     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
6108     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
6109     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6110     ok(pf_exists("msitest"), "Directory deleted\n");
6111
6112     r = MsiInstallProductA(msifile, NULL);
6113     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6114     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
6115     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
6116     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
6117     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6118     ok(pf_exists("msitest"), "Directory deleted\n");
6119
6120     delete_pf("msitest\\cabout\\blocker", TRUE);
6121
6122     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6124     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
6125     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
6126
6127     DeleteFile(msifile);
6128     DeleteFile("msitest\\hydrogen");
6129     DeleteFile("msitest\\helium");
6130     DeleteFile("msitest\\lithium");
6131     RemoveDirectory("msitest");
6132 }
6133
6134 static void test_movefiles(void)
6135 {
6136     UINT r;
6137     char props[MAX_PATH];
6138
6139     CreateDirectoryA("msitest", NULL);
6140     create_file("msitest\\augustus", 100);
6141     create_file("cameroon", 100);
6142     create_file("djibouti", 100);
6143     create_file("egypt", 100);
6144     create_file("finland", 100);
6145     create_file("gambai", 100);
6146     create_file("honduras", 100);
6147     create_file("msitest\\india", 100);
6148     create_file("japan", 100);
6149     create_file("kenya", 100);
6150     CreateDirectoryA("latvia", NULL);
6151     create_file("nauru", 100);
6152     create_file("peru", 100);
6153     create_file("apple", 100);
6154     create_file("application", 100);
6155     create_file("ape", 100);
6156     create_file("foo", 100);
6157     create_file("fao", 100);
6158     create_file("fbod", 100);
6159     create_file("budding", 100);
6160     create_file("buddy", 100);
6161     create_file("bud", 100);
6162     create_file("bar", 100);
6163     create_file("bur", 100);
6164     create_file("bird", 100);
6165
6166     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
6167
6168     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6169
6170     /* if the source or dest property is not a full path,
6171      * windows tries to access it as a network resource
6172      */
6173
6174     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
6175             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
6176             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
6177
6178     r = MsiInstallProductA(msifile, props);
6179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6180     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6181     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
6182     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
6183     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
6184     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
6185     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
6186     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
6187     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
6188     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
6189     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
6190     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
6191     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
6192     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
6193     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
6194     /* either apple or application will be moved depending on directory order */
6195     if (!delete_pf("msitest\\apple", TRUE))
6196         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
6197     else
6198         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
6199     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
6200     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
6201     /* either fao or foo will be moved depending on directory order */
6202     if (delete_pf("msitest\\foo", TRUE))
6203         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
6204     else
6205         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
6206     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
6207     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
6208     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
6209     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
6210     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
6211     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
6212     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
6213     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
6214     ok(delete_pf("msitest", FALSE), "File not installed\n");
6215     ok(DeleteFileA("cameroon"), "File moved\n");
6216     ok(!DeleteFileA("djibouti"), "File not moved\n");
6217     ok(DeleteFileA("egypt"), "File moved\n");
6218     ok(DeleteFileA("finland"), "File moved\n");
6219     ok(DeleteFileA("gambai"), "File moved\n");
6220     ok(!DeleteFileA("honduras"), "File not moved\n");
6221     ok(DeleteFileA("msitest\\india"), "File moved\n");
6222     ok(DeleteFileA("japan"), "File moved\n");
6223     ok(!DeleteFileA("kenya"), "File not moved\n");
6224     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
6225     ok(!DeleteFileA("nauru"), "File not moved\n");
6226     ok(!DeleteFileA("peru"), "File not moved\n");
6227     ok(!DeleteFileA("apple"), "File not moved\n");
6228     ok(!DeleteFileA("application"), "File not moved\n");
6229     ok(DeleteFileA("ape"), "File moved\n");
6230     ok(!DeleteFileA("foo"), "File not moved\n");
6231     ok(!DeleteFileA("fao"), "File not moved\n");
6232     ok(DeleteFileA("fbod"), "File moved\n");
6233     ok(!DeleteFileA("budding"), "File not moved\n");
6234     ok(!DeleteFileA("buddy"), "File not moved\n");
6235     ok(DeleteFileA("bud"), "File moved\n");
6236     ok(!DeleteFileA("bar"), "File not moved\n");
6237     ok(!DeleteFileA("bur"), "File not moved\n");
6238     ok(DeleteFileA("bird"), "File moved\n");
6239
6240     DeleteFile("msitest\\augustus");
6241     RemoveDirectory("msitest");
6242     DeleteFile(msifile);
6243 }
6244
6245 static void test_missingcab(void)
6246 {
6247     UINT r;
6248
6249     CreateDirectoryA("msitest", NULL);
6250     create_file("msitest\\augustus", 500);
6251     create_file("maximus", 500);
6252
6253     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
6254
6255     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6256
6257     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6258
6259     create_pf("msitest", FALSE);
6260     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6261
6262     r = MsiInstallProductA(msifile, NULL);
6263     ok(r == ERROR_SUCCESS ||
6264        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
6265        "Expected ERROR_SUCCESS, got %u\n", r);
6266     if (r == ERROR_SUCCESS)
6267     {
6268       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6269       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6270     }
6271     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
6272     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
6273     ok(delete_pf("msitest", FALSE), "File not installed\n");
6274
6275     create_pf("msitest", FALSE);
6276     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6277     create_pf("msitest\\gaius", TRUE);
6278
6279     r = MsiInstallProductA(msifile, "GAIUS=1");
6280     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6281     todo_wine
6282     {
6283         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
6284         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6285     }
6286     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
6287     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
6288     ok(delete_pf("msitest", FALSE), "File not installed\n");
6289
6290     DeleteFile("msitest\\augustus");
6291     RemoveDirectory("msitest");
6292     DeleteFile("maximus");
6293     DeleteFile("test1.cab");
6294     DeleteFile(msifile);
6295 }
6296
6297 static void test_duplicatefiles(void)
6298 {
6299     UINT r;
6300
6301     CreateDirectoryA("msitest", NULL);
6302     create_file("msitest\\maximus", 500);
6303     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
6304
6305     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6306
6307     /* fails if the destination folder is not a valid property */
6308
6309     r = MsiInstallProductA(msifile, NULL);
6310     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6311     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6312     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
6313     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
6314     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
6315     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
6316     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
6317     ok(delete_pf("msitest", FALSE), "File not installed\n");
6318
6319     DeleteFile("msitest\\maximus");
6320     RemoveDirectory("msitest");
6321     DeleteFile(msifile);
6322 }
6323
6324 static void test_writeregistryvalues(void)
6325 {
6326     UINT r;
6327     LONG res;
6328     HKEY hkey;
6329     DWORD type, size;
6330     CHAR path[MAX_PATH];
6331
6332     CreateDirectoryA("msitest", NULL);
6333     create_file("msitest\\augustus", 500);
6334
6335     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
6336
6337     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6338
6339     r = MsiInstallProductA(msifile, NULL);
6340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6341     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6342     ok(delete_pf("msitest", FALSE), "File installed\n");
6343
6344     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
6345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6346
6347     size = MAX_PATH;
6348     type = REG_MULTI_SZ;
6349     memset(path, 'a', MAX_PATH);
6350     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
6351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6352     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
6353     ok(size == 15, "Expected 15, got %d\n", size);
6354     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
6355
6356     DeleteFile(msifile);
6357     DeleteFile("msitest\\augustus");
6358     RemoveDirectory("msitest");
6359
6360     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
6361     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
6362 }
6363
6364 static void test_sourcefolder(void)
6365 {
6366     UINT r;
6367
6368     CreateDirectoryA("msitest", NULL);
6369     create_file("augustus", 500);
6370
6371     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
6372
6373     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6374
6375     r = MsiInstallProductA(msifile, NULL);
6376     ok(r == ERROR_INSTALL_FAILURE,
6377        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6378     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6379     todo_wine
6380     {
6381         ok(!delete_pf("msitest", FALSE), "File installed\n");
6382     }
6383
6384     RemoveDirectoryA("msitest");
6385
6386     r = MsiInstallProductA(msifile, NULL);
6387     ok(r == ERROR_INSTALL_FAILURE,
6388        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6389     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6390     todo_wine
6391     {
6392         ok(!delete_pf("msitest", FALSE), "File installed\n");
6393     }
6394
6395     DeleteFile(msifile);
6396     DeleteFile("augustus");
6397 }
6398
6399 static void test_customaction51(void)
6400 {
6401     UINT r;
6402
6403     CreateDirectoryA("msitest", NULL);
6404     create_file("msitest\\augustus", 500);
6405
6406     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6407
6408     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6409
6410     r = MsiInstallProductA(msifile, NULL);
6411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6412     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6413     ok(delete_pf("msitest", FALSE), "File installed\n");
6414
6415     DeleteFile(msifile);
6416     DeleteFile("msitest\\augustus");
6417     RemoveDirectory("msitest");
6418 }
6419
6420 static void test_installstate(void)
6421 {
6422     UINT r;
6423
6424     CreateDirectoryA("msitest", NULL);
6425     create_file("msitest\\alpha", 500);
6426     create_file("msitest\\beta", 500);
6427     create_file("msitest\\gamma", 500);
6428     create_file("msitest\\theta", 500);
6429     create_file("msitest\\delta", 500);
6430     create_file("msitest\\epsilon", 500);
6431     create_file("msitest\\zeta", 500);
6432     create_file("msitest\\iota", 500);
6433     create_file("msitest\\eta", 500);
6434     create_file("msitest\\kappa", 500);
6435     create_file("msitest\\lambda", 500);
6436     create_file("msitest\\mu", 500);
6437
6438     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
6439
6440     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6441
6442     r = MsiInstallProductA(msifile, NULL);
6443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6444     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6445     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6446     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6447     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6448     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6449     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6450     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6451     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6452     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6453     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6454     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6455     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6456     ok(delete_pf("msitest", FALSE), "File not installed\n");
6457
6458     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
6459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6460     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6461     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6462     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6463     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6464     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6465     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
6466     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6467     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6468     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
6469     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6470     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6471     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6472     ok(delete_pf("msitest", FALSE), "File not installed\n");
6473
6474     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
6475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6476     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6477     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6478     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6479     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6480     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6481     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6482     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6483     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6484     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6485     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6486     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6487     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6488     ok(delete_pf("msitest", FALSE), "File not installed\n");
6489
6490     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
6491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6492     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
6493     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6494     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6495     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
6496     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6497     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6498     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6499     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6500     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6501     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6502     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6503     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6504     ok(!delete_pf("msitest", FALSE), "File installed\n");
6505
6506     DeleteFile(msifile);
6507     DeleteFile("msitest\\alpha");
6508     DeleteFile("msitest\\beta");
6509     DeleteFile("msitest\\gamma");
6510     DeleteFile("msitest\\theta");
6511     DeleteFile("msitest\\delta");
6512     DeleteFile("msitest\\epsilon");
6513     DeleteFile("msitest\\zeta");
6514     DeleteFile("msitest\\iota");
6515     DeleteFile("msitest\\eta");
6516     DeleteFile("msitest\\kappa");
6517     DeleteFile("msitest\\lambda");
6518     DeleteFile("msitest\\mu");
6519     RemoveDirectory("msitest");
6520 }
6521
6522 struct sourcepathmap
6523 {
6524     BOOL sost; /* shortone\shorttwo */
6525     BOOL solt; /* shortone\longtwo */
6526     BOOL lost; /* longone\shorttwo */
6527     BOOL lolt; /* longone\longtwo */
6528     BOOL soste; /* shortone\shorttwo source exists */
6529     BOOL solte; /* shortone\longtwo source exists */
6530     BOOL loste; /* longone\shorttwo source exists */
6531     BOOL lolte; /* longone\longtwo source exists */
6532     UINT err;
6533     DWORD size;
6534 } spmap[256] =
6535 {
6536     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6537     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6538     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6539     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6540     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6541     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6542     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6543     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6544     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6545     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6546     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6547     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6548     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6549     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6550     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6551     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6552     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6553     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6554     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6555     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6556     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6557     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6558     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6559     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6560     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6561     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6562     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6563     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6564     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6565     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6566     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6567     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6568     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6569     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6570     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6571     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6572     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6573     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6574     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6575     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6576     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6577     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6578     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6579     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6580     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6581     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6582     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6583     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6584     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6585     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6586     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6587     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6588     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6589     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6590     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6591     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6592     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6593     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6594     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6595     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6596     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6597     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6598     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6599     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6600     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6601     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6602     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6603     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6604     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6605     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6606     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6607     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6608     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6609     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6610     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6611     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6612     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6613     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6614     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6615     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6616     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6617     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6618     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6619     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6620     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6621     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6622     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6623     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6624     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6625     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6626     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6627     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6628     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6629     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6630     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6631     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6632     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6633     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6634     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6635     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6636     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6637     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6638     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6639     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6640     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6641     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6642     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6643     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6644     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6645     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6646     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6647     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6648     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6649     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6650     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6651     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6652     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6653     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6654     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6655     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6656     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6657     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6658     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6659     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6660     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6661     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6662     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6663     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6664     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6665     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6666     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6667     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6668     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6669     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6670     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6671     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6672     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6673     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6674     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6675     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6676     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6677     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6678     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6679     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6680     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6681     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6682     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6683     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6684     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6685     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6686     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6687     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6688     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6689     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6690     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6691     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6692     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6693     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6694     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6695     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6696     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6697     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6698     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6699     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6700     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6701     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6702     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6703     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6704     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6705     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6706     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6707     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6708     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6709     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6710     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6711     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6712     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6713     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6714     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6715     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6716     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6717     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6718     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6719     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6720     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6721     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6722     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6723     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6724     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6725     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6726     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6727     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6728     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6729     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6730     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6731     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6732     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6733     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6734     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6735     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6736     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6737     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6738     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6739     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6740     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6741     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6742     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6743     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6744     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6745     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6746     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6747     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6748     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6749     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6750     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6751     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6752     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6753     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6754     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6755     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6756     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6757     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6758     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6759     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6760     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6761     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6762     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6763     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6764     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6765     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6766     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6767     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6768     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6769     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6770     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6771     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6772     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6773     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6774     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6775     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6776     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6777     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6778     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6779     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6780     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6781     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6782     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6783     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6784     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6785     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6786     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6787     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6788     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6789     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6790     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6791     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6792 };
6793
6794 static DWORD get_pf_file_size(LPCSTR file)
6795 {
6796     CHAR path[MAX_PATH];
6797     HANDLE hfile;
6798     DWORD size;
6799
6800     lstrcpyA(path, PROG_FILES_DIR);
6801     lstrcatA(path, "\\");
6802     lstrcatA(path, file);
6803
6804     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
6805     if (hfile == INVALID_HANDLE_VALUE)
6806         return 0;
6807
6808     size = GetFileSize(hfile, NULL);
6809     CloseHandle(hfile);
6810     return size;
6811 }
6812
6813 static void test_sourcepath(void)
6814 {
6815     UINT r, i;
6816
6817     if (!winetest_interactive)
6818     {
6819         skip("Run in interactive mode to run source path tests.\n");
6820         return;
6821     }
6822
6823     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
6824
6825     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6826
6827     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
6828     {
6829         if (spmap[i].sost)
6830         {
6831             CreateDirectoryA("shortone", NULL);
6832             CreateDirectoryA("shortone\\shorttwo", NULL);
6833         }
6834
6835         if (spmap[i].solt)
6836         {
6837             CreateDirectoryA("shortone", NULL);
6838             CreateDirectoryA("shortone\\longtwo", NULL);
6839         }
6840
6841         if (spmap[i].lost)
6842         {
6843             CreateDirectoryA("longone", NULL);
6844             CreateDirectoryA("longone\\shorttwo", NULL);
6845         }
6846
6847         if (spmap[i].lolt)
6848         {
6849             CreateDirectoryA("longone", NULL);
6850             CreateDirectoryA("longone\\longtwo", NULL);
6851         }
6852
6853         if (spmap[i].soste)
6854             create_file("shortone\\shorttwo\\augustus", 50);
6855         if (spmap[i].solte)
6856             create_file("shortone\\longtwo\\augustus", 100);
6857         if (spmap[i].loste)
6858             create_file("longone\\shorttwo\\augustus", 150);
6859         if (spmap[i].lolte)
6860             create_file("longone\\longtwo\\augustus", 200);
6861
6862         r = MsiInstallProductA(msifile, NULL);
6863         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
6864         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
6865            "%d: Expected %d, got %d\n", i, spmap[i].size,
6866            get_pf_file_size("msitest\\augustus"));
6867
6868         if (r == ERROR_SUCCESS)
6869         {
6870             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
6871             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
6872         }
6873         else
6874         {
6875             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
6876             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
6877         }
6878
6879         DeleteFileA("shortone\\shorttwo\\augustus");
6880         DeleteFileA("shortone\\longtwo\\augustus");
6881         DeleteFileA("longone\\shorttwo\\augustus");
6882         DeleteFileA("longone\\longtwo\\augustus");
6883         RemoveDirectoryA("shortone\\shorttwo");
6884         RemoveDirectoryA("shortone\\longtwo");
6885         RemoveDirectoryA("longone\\shorttwo");
6886         RemoveDirectoryA("longone\\longtwo");
6887         RemoveDirectoryA("shortone");
6888         RemoveDirectoryA("longone");
6889     }
6890
6891     DeleteFileA(msifile);
6892 }
6893
6894 static void test_MsiConfigureProductEx(void)
6895 {
6896     UINT r;
6897     LONG res;
6898     DWORD type, size;
6899     HKEY props, source;
6900     CHAR keypath[MAX_PATH * 2];
6901     CHAR localpack[MAX_PATH];
6902
6903     if (on_win9x)
6904     {
6905         win_skip("Different registry keys on Win9x and WinMe\n");
6906         return;
6907     }
6908
6909     CreateDirectoryA("msitest", NULL);
6910     create_file("msitest\\hydrogen", 500);
6911     create_file("msitest\\helium", 500);
6912     create_file("msitest\\lithium", 500);
6913
6914     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6915
6916     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6917
6918     /* NULL szProduct */
6919     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
6920                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6921     ok(r == ERROR_INVALID_PARAMETER,
6922        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6923
6924     /* empty szProduct */
6925     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
6926                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6927     ok(r == ERROR_INVALID_PARAMETER,
6928        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6929
6930     /* garbage szProduct */
6931     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
6932                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6933     ok(r == ERROR_INVALID_PARAMETER,
6934        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6935
6936     /* guid without brackets */
6937     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6938                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6939                                "PROPVAR=42");
6940     ok(r == ERROR_INVALID_PARAMETER,
6941        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6942
6943     /* guid with brackets */
6944     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6945                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6946                                "PROPVAR=42");
6947     ok(r == ERROR_UNKNOWN_PRODUCT,
6948        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6949
6950     /* same length as guid, but random */
6951     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
6952                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6953                                "PROPVAR=42");
6954     ok(r == ERROR_UNKNOWN_PRODUCT,
6955        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6956
6957     /* product not installed yet */
6958     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6959                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6960                                "PROPVAR=42");
6961     ok(r == ERROR_UNKNOWN_PRODUCT,
6962        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6963
6964     /* install the product, per-user unmanaged */
6965     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
6966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6967     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6968     ok(pf_exists("msitest\\helium"), "File not installed\n");
6969     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6970     ok(pf_exists("msitest"), "File not installed\n");
6971
6972     /* product is installed per-user managed, remove it */
6973     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6974                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6975                                "PROPVAR=42");
6976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6977     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6978     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6979     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6980     todo_wine
6981     {
6982         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6983     }
6984
6985     /* product has been removed */
6986     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6987                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6988                                "PROPVAR=42");
6989     ok(r == ERROR_UNKNOWN_PRODUCT,
6990        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
6991
6992     /* install the product, machine */
6993     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6995     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6996     ok(pf_exists("msitest\\helium"), "File not installed\n");
6997     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6998     ok(pf_exists("msitest"), "File not installed\n");
6999
7000     /* product is installed machine, remove it */
7001     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7002                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7003                                "PROPVAR=42");
7004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7005     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7006     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7007     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7008     todo_wine
7009     {
7010         ok(!delete_pf("msitest", FALSE), "File not removed\n");
7011     }
7012
7013     /* product has been removed */
7014     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7015                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7016                                "PROPVAR=42");
7017     ok(r == ERROR_UNKNOWN_PRODUCT,
7018        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7019
7020     /* install the product, machine */
7021     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7022     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7023     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7024     ok(pf_exists("msitest\\helium"), "File not installed\n");
7025     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7026     ok(pf_exists("msitest"), "File not installed\n");
7027
7028     DeleteFileA(msifile);
7029
7030     /* local msifile is removed */
7031     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7032                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7033                                "PROPVAR=42");
7034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7035     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7036     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7037     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7038     todo_wine
7039     {
7040         ok(!delete_pf("msitest", FALSE), "File not removed\n");
7041     }
7042
7043     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7044
7045     /* install the product, machine */
7046     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7047     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7048     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7049     ok(pf_exists("msitest\\helium"), "File not installed\n");
7050     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7051     ok(pf_exists("msitest"), "File not installed\n");
7052
7053     DeleteFileA(msifile);
7054
7055     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7056     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7057     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7058
7059     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7061
7062     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7063                          (const BYTE *)"C:\\idontexist.msi", 18);
7064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7065
7066     /* LocalPackage is used to find the cached msi package */
7067     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7068                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7069                                "PROPVAR=42");
7070     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7071        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\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     RegCloseKey(props);
7078     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7079
7080     /* LastUsedSource (local msi package) can be used as a last resort */
7081     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7082                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7083                                "PROPVAR=42");
7084     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7085     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7086     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7087     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7088     todo_wine
7089     {
7090         ok(!delete_pf("msitest", FALSE), "File not removed\n");
7091     }
7092
7093     /* install the product, machine */
7094     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7096     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7097     ok(pf_exists("msitest\\helium"), "File not installed\n");
7098     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7099     ok(pf_exists("msitest"), "File not installed\n");
7100
7101     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7102     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7103     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7104
7105     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7107
7108     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7109                          (const BYTE *)"C:\\idontexist.msi", 18);
7110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7111
7112     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
7113     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
7114
7115     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
7116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7117
7118     type = REG_SZ;
7119     size = MAX_PATH;
7120     res = RegQueryValueExA(source, "PackageName", NULL, &type,
7121                            (LPBYTE)localpack, &size);
7122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7123
7124     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7125                          (const BYTE *)"idontexist.msi", 15);
7126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7127
7128     /* SourceList is altered */
7129     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7130                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7131                                "PROPVAR=42");
7132     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7133        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7134     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7135     ok(pf_exists("msitest\\helium"), "File not installed\n");
7136     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7137     ok(pf_exists("msitest"), "File not installed\n");
7138
7139     /* restore the SourceList */
7140     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7141                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
7142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7143
7144     /* finally remove the product */
7145     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7146                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7147                                "PROPVAR=42");
7148     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7149     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7150     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7151     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7152     todo_wine
7153     {
7154         ok(!delete_pf("msitest", FALSE), "File not removed\n");
7155     }
7156
7157     DeleteFileA(msifile);
7158     RegCloseKey(source);
7159     RegCloseKey(props);
7160     DeleteFileA("msitest\\hydrogen");
7161     DeleteFileA("msitest\\helium");
7162     DeleteFileA("msitest\\lithium");
7163     RemoveDirectoryA("msitest");
7164 }
7165
7166 static void test_missingcomponent(void)
7167 {
7168     UINT r;
7169
7170     CreateDirectoryA("msitest", NULL);
7171     create_file("msitest\\hydrogen", 500);
7172     create_file("msitest\\helium", 500);
7173     create_file("msitest\\lithium", 500);
7174     create_file("beryllium", 500);
7175
7176     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
7177
7178     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7179
7180     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7182     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7183     ok(pf_exists("msitest\\helium"), "File not installed\n");
7184     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7185     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7186     ok(pf_exists("msitest"), "File not installed\n");
7187
7188     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
7189     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7190     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7191     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7192     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7193     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7194     todo_wine
7195     {
7196         ok(!delete_pf("msitest", FALSE), "File not removed\n");
7197     }
7198
7199     DeleteFileA(msifile);
7200     DeleteFileA("msitest\\hydrogen");
7201     DeleteFileA("msitest\\helium");
7202     DeleteFileA("msitest\\lithium");
7203     DeleteFileA("beryllium");
7204     RemoveDirectoryA("msitest");
7205 }
7206
7207 static void test_sourcedirprop(void)
7208 {
7209     UINT r;
7210     CHAR props[MAX_PATH];
7211
7212     CreateDirectoryA("msitest", NULL);
7213     create_file("msitest\\augustus", 500);
7214
7215     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
7216
7217     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7218
7219     r = MsiInstallProductA(msifile, NULL);
7220     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7221     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7222     ok(delete_pf("msitest", FALSE), "File installed\n");
7223
7224     DeleteFile("msitest\\augustus");
7225     RemoveDirectory("msitest");
7226
7227     CreateDirectoryA("altsource", NULL);
7228     CreateDirectoryA("altsource\\msitest", NULL);
7229     create_file("altsource\\msitest\\augustus", 500);
7230
7231     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
7232
7233     r = MsiInstallProductA(msifile, props);
7234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7235     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7236     ok(delete_pf("msitest", FALSE), "File installed\n");
7237
7238     DeleteFile(msifile);
7239     DeleteFile("altsource\\msitest\\augustus");
7240     RemoveDirectory("altsource\\msitest");
7241     RemoveDirectory("altsource");
7242 }
7243
7244 static void test_adminimage(void)
7245 {
7246     UINT r;
7247
7248     CreateDirectoryA("msitest", NULL);
7249     CreateDirectoryA("msitest\\first", NULL);
7250     CreateDirectoryA("msitest\\second", NULL);
7251     CreateDirectoryA("msitest\\cabout", NULL);
7252     CreateDirectoryA("msitest\\cabout\\new", NULL);
7253     create_file("msitest\\one.txt", 100);
7254     create_file("msitest\\first\\two.txt", 100);
7255     create_file("msitest\\second\\three.txt", 100);
7256     create_file("msitest\\cabout\\four.txt", 100);
7257     create_file("msitest\\cabout\\new\\five.txt", 100);
7258     create_file("msitest\\filename", 100);
7259     create_file("msitest\\service.exe", 100);
7260
7261     create_database_wordcount(msifile, ai_tables,
7262                               sizeof(ai_tables) / sizeof(msi_table),
7263                               msidbSumInfoSourceTypeAdminImage);
7264
7265     r = MsiInstallProductA(msifile, NULL);
7266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7267
7268     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7269     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7270     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7271     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7272     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7273     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7274     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7275     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7276     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7277     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7278     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7279     ok(delete_pf("msitest", FALSE), "File not installed\n");
7280
7281     DeleteFileA("msitest.msi");
7282     DeleteFileA("msitest\\cabout\\new\\five.txt");
7283     DeleteFileA("msitest\\cabout\\four.txt");
7284     DeleteFileA("msitest\\second\\three.txt");
7285     DeleteFileA("msitest\\first\\two.txt");
7286     DeleteFileA("msitest\\one.txt");
7287     DeleteFileA("msitest\\service.exe");
7288     DeleteFileA("msitest\\filename");
7289     RemoveDirectoryA("msitest\\cabout\\new");
7290     RemoveDirectoryA("msitest\\cabout");
7291     RemoveDirectoryA("msitest\\second");
7292     RemoveDirectoryA("msitest\\first");
7293     RemoveDirectoryA("msitest");
7294 }
7295
7296 static void test_propcase(void)
7297 {
7298     UINT r;
7299
7300     CreateDirectoryA("msitest", NULL);
7301     create_file("msitest\\augustus", 500);
7302
7303     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
7304
7305     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7306
7307     r = MsiInstallProductA(msifile, "MyProp=42");
7308     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7309     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
7310     ok(delete_pf("msitest", FALSE), "File not installed\n");
7311
7312     DeleteFile(msifile);
7313     DeleteFile("msitest\\augustus");
7314     RemoveDirectory("msitest");
7315 }
7316
7317 static void test_int_widths( void )
7318 {
7319     static const char int0[] = "int0\ni0\nint0\tint0\n1";
7320     static const char int1[] = "int1\ni1\nint1\tint1\n1";
7321     static const char int2[] = "int2\ni2\nint2\tint2\n1";
7322     static const char int3[] = "int3\ni3\nint3\tint3\n1";
7323     static const char int4[] = "int4\ni4\nint4\tint4\n1";
7324     static const char int5[] = "int5\ni5\nint5\tint5\n1";
7325     static const char int8[] = "int8\ni8\nint8\tint8\n1";
7326
7327     static const struct
7328     {
7329         const char  *data;
7330         unsigned int size;
7331         UINT         ret;
7332     }
7333     tests[] =
7334     {
7335         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
7336         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
7337         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
7338         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
7339         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
7340         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
7341         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
7342     };
7343
7344     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
7345     MSIHANDLE db;
7346     UINT r, i;
7347
7348     GetTempPathA(MAX_PATH, tmpdir);
7349     CreateDirectoryA(tmpdir, NULL);
7350
7351     strcpy(msitable, tmpdir);
7352     strcat(msitable, "\\msitable.idt");
7353
7354     strcpy(msidb, tmpdir);
7355     strcat(msidb, "\\msitest.msi");
7356
7357     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
7358     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7359
7360     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
7361     {
7362         write_file(msitable, tests[i].data, tests[i].size);
7363
7364         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
7365         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
7366
7367         r = MsiDatabaseCommit(db);
7368         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7369         DeleteFileA(msitable);
7370     }
7371
7372     MsiCloseHandle(db);
7373     DeleteFileA(msidb);
7374     RemoveDirectoryA(tmpdir);
7375 }
7376
7377 static void test_shortcut(void)
7378 {
7379     UINT r;
7380     HRESULT hr;
7381
7382     create_test_files();
7383     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
7384
7385     r = MsiInstallProductA(msifile, NULL);
7386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7387
7388     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
7389     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7390
7391     r = MsiInstallProductA(msifile, NULL);
7392     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7393
7394     CoUninitialize();
7395
7396     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7397     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7398
7399     r = MsiInstallProductA(msifile, NULL);
7400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7401
7402     CoUninitialize();
7403
7404     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7405     delete_pf("msitest\\cabout\\new", FALSE);
7406     delete_pf("msitest\\cabout\\four.txt", TRUE);
7407     delete_pf("msitest\\cabout", FALSE);
7408     delete_pf("msitest\\changed\\three.txt", TRUE);
7409     delete_pf("msitest\\changed", FALSE);
7410     delete_pf("msitest\\first\\two.txt", TRUE);
7411     delete_pf("msitest\\first", FALSE);
7412     delete_pf("msitest\\filename", TRUE);
7413     delete_pf("msitest\\one.txt", TRUE);
7414     delete_pf("msitest\\service.exe", TRUE);
7415     delete_pf("msitest\\Shortcut.lnk", TRUE);
7416     delete_pf("msitest", FALSE);
7417     delete_test_files();
7418 }
7419
7420 static void test_envvar(void)
7421 {
7422     UINT r;
7423     HKEY env;
7424     LONG res;
7425     DWORD type, size;
7426     char buffer[16];
7427     UINT i;
7428
7429     if (on_win9x)
7430     {
7431         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
7432         return;
7433     }
7434
7435     create_test_files();
7436     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
7437
7438     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
7439     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7440
7441     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
7442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7443
7444     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
7445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7446
7447     r = MsiInstallProductA(msifile, NULL);
7448     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7449
7450     type = REG_NONE;
7451     size = sizeof(buffer);
7452     buffer[0] = 0;
7453     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
7454     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7455     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7456     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7457
7458     res = RegDeleteValueA(env, "MSITESTVAR1");
7459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7460
7461     type = REG_NONE;
7462     size = sizeof(buffer);
7463     buffer[0] = 0;
7464     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
7465     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7466     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7467     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7468
7469     res = RegDeleteValueA(env, "MSITESTVAR2");
7470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7471
7472     res = RegDeleteValueA(env, "MSITESTVAR3");
7473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7474
7475     res = RegDeleteValueA(env, "MSITESTVAR4");
7476     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7477
7478     res = RegDeleteValueA(env, "MSITESTVAR5");
7479     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7480
7481     res = RegDeleteValueA(env, "MSITESTVAR6");
7482     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7483
7484     res = RegDeleteValueA(env, "MSITESTVAR7");
7485     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7486
7487     res = RegDeleteValueA(env, "MSITESTVAR8");
7488     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7489
7490     res = RegDeleteValueA(env, "MSITESTVAR9");
7491     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7492
7493     res = RegDeleteValueA(env, "MSITESTVAR10");
7494     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7495
7496     i = 11;
7497     while (environment_dat_results[(i-11)]) {
7498         char name[20];
7499         sprintf(name, "MSITESTVAR%d", i);
7500
7501         type = REG_NONE;
7502         size = sizeof(buffer);
7503         buffer[0] = 0;
7504         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
7505         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7506         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
7507         ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n",
7508            i, environment_dat_results[(i-11)], buffer);
7509
7510         res = RegDeleteValueA(env, name);
7511         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7512         i++;
7513     }
7514
7515
7516     RegCloseKey(env);
7517     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7518     delete_pf("msitest\\cabout\\new", FALSE);
7519     delete_pf("msitest\\cabout\\four.txt", TRUE);
7520     delete_pf("msitest\\cabout", FALSE);
7521     delete_pf("msitest\\changed\\three.txt", TRUE);
7522     delete_pf("msitest\\changed", FALSE);
7523     delete_pf("msitest\\first\\two.txt", TRUE);
7524     delete_pf("msitest\\first", FALSE);
7525     delete_pf("msitest\\filename", TRUE);
7526     delete_pf("msitest\\one.txt", TRUE);
7527     delete_pf("msitest\\service.exe", TRUE);
7528     delete_pf("msitest", FALSE);
7529     delete_test_files();
7530 }
7531
7532 static void test_preselected(void)
7533 {
7534     UINT r;
7535
7536     create_test_files();
7537     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
7538
7539     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
7540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7541
7542     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
7543     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
7544     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
7545     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
7546     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
7547     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
7548     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
7549     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
7550     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
7551     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7552     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
7553     ok(delete_pf("msitest", FALSE), "File not installed\n");
7554
7555     r = MsiInstallProductA(msifile, NULL);
7556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7557
7558     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7559     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7560     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7561     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7562     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7563     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7564     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7565     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7566     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7567     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7568     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7569     ok(delete_pf("msitest", FALSE), "File not installed\n");
7570     delete_test_files();
7571 }
7572
7573 static void test_installed_prop(void)
7574 {
7575     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
7576     UINT r;
7577
7578     create_test_files();
7579     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
7580
7581     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7582
7583     r = MsiInstallProductA(msifile, "FULL=1");
7584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7585
7586     r = MsiInstallProductA(msifile, "FULL=1");
7587     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7588
7589     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
7590     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7591
7592     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7593     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7594     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7595     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7596     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7597     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7598     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7599     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7600     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7601     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7602     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7603     ok(delete_pf("msitest", FALSE), "File not installed\n");
7604
7605     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7606     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7607
7608     delete_test_files();
7609 }
7610
7611 static void test_allusers_prop(void)
7612 {
7613     UINT r;
7614
7615     create_test_files();
7616     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
7617
7618     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7619
7620     /* ALLUSERS property unset */
7621     r = MsiInstallProductA(msifile, "FULL=1");
7622     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7623
7624     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7625     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7626     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7627     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7628     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7629     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7630     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7631     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7632     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7633     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7634     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7635     ok(delete_pf("msitest", FALSE), "File not installed\n");
7636
7637     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7638     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7639
7640     delete_test_files();
7641
7642     create_test_files();
7643     create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
7644
7645     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7646
7647     /* ALLUSERS property set to 1 */
7648     r = MsiInstallProductA(msifile, "FULL=1");
7649     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7650
7651     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7652     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7653     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7654     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7655     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7656     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7657     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7658     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7659     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7660     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7661     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7662     ok(delete_pf("msitest", FALSE), "File not installed\n");
7663
7664     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7665     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7666
7667     delete_test_files();
7668
7669     create_test_files();
7670     create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
7671
7672     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7673
7674     /* ALLUSERS property set to 2 */
7675     r = MsiInstallProductA(msifile, "FULL=1");
7676     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
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     create_test_files();
7697     create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
7698
7699     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7700
7701     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
7702     r = MsiInstallProductA(msifile, "FULL=1");
7703     if (r == ERROR_SUCCESS)
7704     {
7705         /* Win9x/WinMe */
7706         win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n");
7707
7708         ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7709         ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7710         ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7711         ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7712         ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7713         ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7714         ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7715         ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7716         ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7717         ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7718         ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7719         ok(delete_pf("msitest", FALSE), "File not installed\n");
7720
7721         r = MsiInstallProductA(msifile, "REMOVE=ALL");
7722         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7723
7724         delete_test_files();
7725     }
7726     else
7727         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7728 }
7729
7730 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
7731 static char rename_ops[]      = "PendingFileRenameOperations";
7732
7733 static void process_pending_renames(HKEY hkey)
7734 {
7735     char *buf, *src, *dst, *buf2, *buf2ptr;
7736     DWORD size, buf2len = 0;
7737     LONG ret;
7738     BOOL found = FALSE;
7739
7740     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
7741     buf = HeapAlloc(GetProcessHeap(), 0, size);
7742     buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7743     buf[0] = 0;
7744
7745     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
7746     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
7747
7748     for (src = buf; *src; src = dst + strlen(dst) + 1)
7749     {
7750         DWORD flags = MOVEFILE_COPY_ALLOWED;
7751
7752         dst = src + strlen(src) + 1;
7753
7754         if (!strstr(src, "msitest"))
7755         {
7756             lstrcpyA(buf2ptr, src);
7757             buf2len += strlen(src) + 1;
7758             buf2ptr += strlen(src) + 1;
7759             if (*dst)
7760             {
7761                 lstrcpyA(buf2ptr, dst);
7762                 buf2ptr += strlen(dst) + 1;
7763                 buf2len += strlen(dst) + 1;
7764             }
7765             buf2ptr++;
7766             buf2len++;
7767             continue;
7768         }
7769
7770         found = TRUE;
7771
7772         if (*dst == '!')
7773         {
7774             flags |= MOVEFILE_REPLACE_EXISTING;
7775             dst++;
7776         }
7777         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
7778         if (*dst)
7779         {
7780             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
7781             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
7782         }
7783         else
7784             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
7785     }
7786
7787     ok(found, "Expected a 'msitest' entry\n");
7788
7789     if (*buf2)
7790     {
7791         buf2len++;
7792         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len);
7793     }
7794     else
7795         RegDeleteValueA(hkey, rename_ops);
7796
7797     HeapFree(GetProcessHeap(), 0, buf);
7798     HeapFree(GetProcessHeap(), 0, buf2);
7799 }
7800
7801 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
7802 {
7803     DWORD len, data_len = strlen(data);
7804     HANDLE handle;
7805     char buf[128];
7806
7807     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7808     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
7809
7810     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
7811     {
7812         CloseHandle(handle);
7813         return !memcmp(buf, data, data_len);
7814     }
7815     CloseHandle(handle);
7816     return FALSE;
7817 }
7818
7819 static void test_file_in_use(void)
7820 {
7821     UINT r;
7822     HANDLE file;
7823     HKEY hkey;
7824     char path[MAX_PATH];
7825
7826     if (on_win9x)
7827     {
7828         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
7829         return;
7830     }
7831
7832     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
7833
7834     CreateDirectoryA("msitest", NULL);
7835     create_file("msitest\\maximus", 500);
7836     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
7837
7838     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7839
7840     lstrcpy(path, PROG_FILES_DIR);
7841     lstrcat(path, "\\msitest");
7842     CreateDirectoryA(path, NULL);
7843
7844     lstrcat(path, "\\maximus");
7845     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
7846
7847     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
7848     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
7849     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
7850     CloseHandle(file);
7851     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
7852
7853     process_pending_renames(hkey);
7854     RegCloseKey(hkey);
7855
7856     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
7857     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
7858     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
7859
7860     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7861     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7862
7863     delete_test_files();
7864 }
7865
7866 static void test_file_in_use_cab(void)
7867 {
7868     UINT r;
7869     HANDLE file;
7870     HKEY hkey;
7871     char path[MAX_PATH];
7872
7873     if (on_win9x)
7874     {
7875         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
7876         return;
7877     }
7878
7879     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
7880
7881     CreateDirectoryA("msitest", NULL);
7882     create_file("maximus", 500);
7883     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
7884     DeleteFile("maximus");
7885
7886     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
7887
7888     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7889
7890     lstrcpy(path, PROG_FILES_DIR);
7891     lstrcat(path, "\\msitest");
7892     CreateDirectoryA(path, NULL);
7893
7894     lstrcat(path, "\\maximus");
7895     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
7896
7897     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
7898     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
7899     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
7900     CloseHandle(file);
7901     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
7902
7903     process_pending_renames(hkey);
7904     RegCloseKey(hkey);
7905
7906     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
7907     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
7908     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
7909
7910     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7912
7913     delete_cab_files();
7914     delete_test_files();
7915 }
7916
7917 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
7918 {
7919     return IDOK;
7920 }
7921
7922 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
7923 {
7924     return IDOK;
7925 }
7926
7927 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
7928 {
7929     return IDOK;
7930 }
7931
7932 static void test_MsiSetExternalUI(void)
7933 {
7934     INSTALLUI_HANDLERA ret_a;
7935     INSTALLUI_HANDLERW ret_w;
7936     INSTALLUI_HANDLER_RECORD prev;
7937     UINT error;
7938
7939     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
7940     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7941
7942     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
7943     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
7944
7945     /* Not present before Installer 3.1 */
7946     if (!pMsiSetExternalUIRecord) {
7947         win_skip("MsiSetExternalUIRecord is not available\n");
7948         return;
7949     }
7950
7951     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
7952     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7953     ok(prev == NULL, "expected NULL, got %p\n", prev);
7954
7955     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7956     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
7957     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7958     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
7959
7960     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
7961     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7962
7963     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
7964     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
7965
7966     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
7967     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7968
7969     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
7970     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7971
7972     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7973     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
7974     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7975     ok(prev == NULL, "expected NULL, got %p\n", prev);
7976
7977     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
7978     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7979
7980     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
7981     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7982
7983     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7984     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
7985     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7986     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
7987
7988     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
7989     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7990
7991     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
7992     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7993 }
7994
7995 static void test_feature_override(void)
7996 {
7997     UINT r;
7998
7999     create_test_files();
8000     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
8001
8002     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
8003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8004
8005     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8006     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
8007     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8008     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
8009     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8010     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
8011     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8012     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
8013     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8014     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8015     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8016     ok(delete_pf("msitest", FALSE), "File not installed\n");
8017
8018     delete_test_files();
8019 }
8020
8021 static void test_create_folder(void)
8022 {
8023     UINT r;
8024
8025     create_test_files();
8026     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
8027
8028     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8029
8030     r = MsiInstallProductA(msifile, NULL);
8031     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8032
8033     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8034     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8035     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8036     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8037     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8038     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8039     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8040     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8041     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8042     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8043     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8044     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8045
8046     r = MsiInstallProductA(msifile, "LOCAL=Two");
8047     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8048
8049     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8050     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8051     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8052     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8053     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8054     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8055     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8056     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8057     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8058     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8059     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8060     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8061
8062     delete_test_files();
8063 }
8064
8065 static void test_remove_folder(void)
8066 {
8067     UINT r;
8068
8069     create_test_files();
8070     create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table));
8071
8072     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8073
8074     r = MsiInstallProductA(msifile, NULL);
8075     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8076
8077     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8078     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8079     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8080     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8081     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8082     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8083     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8084     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8085     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8086     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8087     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8088     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8089
8090     r = MsiInstallProductA(msifile, "LOCAL=Two");
8091     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8092
8093     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8094     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8095     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8096     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8097     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8098     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8099     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8100     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8101     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8102     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8103     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8104     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8105
8106     delete_test_files();
8107 }
8108
8109 static void test_start_services(void)
8110 {
8111     UINT r;
8112     SC_HANDLE scm, service;
8113     BOOL ret;
8114     DWORD error = ERROR_SUCCESS;
8115
8116     if (on_win9x)
8117     {
8118         win_skip("Services are not implemented on Win9x and WinMe\n");
8119         return;
8120     }
8121     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8122     ok(scm != NULL, "Failed to open the SC Manager\n");
8123     if (!scm) return;
8124
8125     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8126     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
8127     {
8128         win_skip("The 'Spooler' service does not exist\n");
8129         CloseServiceHandle(scm);
8130         return;
8131     }
8132     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
8133     if (!service) {
8134         CloseServiceHandle(scm);
8135         return;
8136     }
8137
8138     ret = StartService(service, 0, NULL);
8139     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
8140     {
8141         skip("Terminal service not available, skipping test\n");
8142         CloseServiceHandle(service);
8143         CloseServiceHandle(scm);
8144         return;
8145     }
8146
8147     CloseServiceHandle(service);
8148     CloseServiceHandle(scm);
8149
8150     create_test_files();
8151     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
8152
8153     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8154
8155     r = MsiInstallProductA(msifile, NULL);
8156     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8157
8158     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8159     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8160     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8161     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8162     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8163     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8164     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8165     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8166     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8167     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8168     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8169     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8170
8171     delete_test_files();
8172
8173     if (error == ERROR_SUCCESS)
8174     {
8175         SERVICE_STATUS status;
8176
8177         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8178         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8179
8180         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
8181         ok(ret, "ControlService failed %u\n", GetLastError());
8182
8183         CloseServiceHandle(service);
8184         CloseServiceHandle(scm);
8185     }
8186 }
8187
8188 static void test_delete_services(void)
8189 {
8190     UINT r;
8191
8192     create_test_files();
8193     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
8194
8195     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8196
8197     r = MsiInstallProductA(msifile, NULL);
8198     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8199
8200     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8201     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8202     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8203     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8204     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8205     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8206     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8207     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8208     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8209     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8210     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8211     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8212
8213     delete_test_files();
8214 }
8215
8216 static void test_self_registration(void)
8217 {
8218     UINT r;
8219
8220     create_test_files();
8221     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
8222
8223     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8224
8225     r = MsiInstallProductA(msifile, NULL);
8226     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8227
8228     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8229     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8230     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8231     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8232     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8233     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8234     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8235     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8236     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8237     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8238     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8239     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8240
8241     delete_test_files();
8242 }
8243
8244 static void test_register_font(void)
8245 {
8246     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
8247     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
8248     LONG ret;
8249     HKEY key;
8250     UINT r;
8251
8252     create_test_files();
8253     create_file("msitest\\font.ttf", 1000);
8254     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
8255
8256     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8257
8258     r = MsiInstallProductA(msifile, NULL);
8259     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8260
8261     ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key);
8262     if (ret)
8263         RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key);
8264
8265     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8266     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8267
8268     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8269     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8270
8271     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8272
8273     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8274     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8275
8276     RegDeleteValueA(key, "msi test font");
8277     RegCloseKey(key);
8278     delete_test_files();
8279 }
8280
8281 static void test_validate_product_id(void)
8282 {
8283     UINT r;
8284
8285     create_test_files();
8286     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
8287
8288     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8289
8290     r = MsiInstallProductA(msifile, NULL);
8291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8292
8293     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
8294     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8295
8296     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
8297     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8298
8299     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
8300     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8301
8302     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8303     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8304     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8305     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8306     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8307     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8308     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8309     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8310     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8311     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8312     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8313     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8314
8315     delete_test_files();
8316 }
8317
8318 static void test_install_remove_odbc(void)
8319 {
8320     UINT r;
8321
8322     create_test_files();
8323     create_file("msitest\\ODBCdriver.dll", 1000);
8324     create_file("msitest\\ODBCdriver2.dll", 1000);
8325     create_file("msitest\\ODBCtranslator.dll", 1000);
8326     create_file("msitest\\ODBCtranslator2.dll", 1000);
8327     create_file("msitest\\ODBCsetup.dll", 1000);
8328     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
8329
8330     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8331
8332     r = MsiInstallProductA(msifile, NULL);
8333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8334
8335     ok(delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not created\n");
8336     ok(delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not created\n");
8337     ok(delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not created\n");
8338     ok(delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not created\n");
8339     ok(delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not created\n");
8340     ok(delete_pf("msitest", FALSE), "directory not created\n");
8341
8342     delete_test_files();
8343 }
8344
8345 static void test_register_typelib(void)
8346 {
8347     UINT r;
8348
8349     create_test_files();
8350     create_file("msitest\\typelib.dll", 1000);
8351     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
8352
8353     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8354
8355     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
8356     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8357
8358     r = MsiInstallProductA(msifile, NULL);
8359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8360
8361     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8363
8364     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
8365     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8366
8367     delete_test_files();
8368 }
8369
8370 static void test_create_remove_shortcut(void)
8371 {
8372     UINT r;
8373
8374     create_test_files();
8375     create_file("msitest\\target.txt", 1000);
8376     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
8377
8378     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8379
8380     r = MsiInstallProductA(msifile, NULL);
8381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8382
8383     ok(pf_exists("msitest\\target.txt"), "file not created\n");
8384     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
8385
8386     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8387     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8388
8389     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
8390     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
8391     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8392
8393     delete_test_files();
8394 }
8395
8396 static void test_publish_components(void)
8397 {
8398     static char keypath[] =
8399         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
8400
8401     UINT r;
8402     LONG res;
8403     HKEY key;
8404
8405     create_test_files();
8406     create_file("msitest\\english.txt", 1000);
8407     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
8408
8409     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8410
8411     r = MsiInstallProductA(msifile, NULL);
8412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8413
8414     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8415     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
8416
8417     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
8418     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
8419     RegCloseKey(key);
8420
8421     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8423
8424     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8425     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
8426
8427     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
8428     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8429     delete_test_files();
8430 }
8431
8432 static void test_remove_duplicate_files(void)
8433 {
8434     UINT r;
8435
8436     create_test_files();
8437     create_file("msitest\\original.txt", 1000);
8438     create_file("msitest\\original2.txt", 1000);
8439     create_file("msitest\\original3.txt", 1000);
8440     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
8441
8442     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8443
8444     r = MsiInstallProductA(msifile, NULL);
8445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8446
8447     ok(pf_exists("msitest\\original.txt"), "file not created\n");
8448     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
8449     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
8450     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
8451     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
8452
8453     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8455
8456     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
8457     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
8458     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
8459     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
8460     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
8461     ok(delete_pf("msitest", FALSE), "directory removed\n");
8462     delete_test_files();
8463 }
8464
8465 static void test_remove_registry_values(void)
8466 {
8467     UINT r;
8468     LONG res;
8469     HKEY key;
8470
8471     create_test_files();
8472     create_file("msitest\\registry.txt", 1000);
8473     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
8474
8475     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8476
8477     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8478     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
8479     RegCloseKey(key);
8480
8481     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8482     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
8483     RegCloseKey(key);
8484
8485     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8486     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8487     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
8488     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8489     RegCloseKey(key);
8490
8491     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8492     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8493     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8494     RegCloseKey(key);
8495
8496     r = MsiInstallProductA(msifile, NULL);
8497     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8498
8499     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8500     ok(res == ERROR_SUCCESS, "key removed\n");
8501     RegCloseKey(key);
8502
8503     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8504     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8505
8506     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8508     RegCloseKey(key);
8509
8510     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8512
8513     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8514     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8515
8516     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8517     ok(res == ERROR_SUCCESS, "key removed\n");
8518     RegCloseKey(key);
8519
8520     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8521     ok(res == ERROR_SUCCESS, "key removed\n");
8522     RegCloseKey(key);
8523
8524     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8525     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8526
8527     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA");
8528     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2");
8529     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine");
8530
8531     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
8532     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8533     delete_test_files();
8534 }
8535
8536 START_TEST(install)
8537 {
8538     DWORD len;
8539     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
8540     STATEMGRSTATUS status;
8541     BOOL ret = FALSE;
8542
8543     init_functionpointers();
8544
8545     on_win9x = check_win9x();
8546
8547     GetCurrentDirectoryA(MAX_PATH, prev_path);
8548     GetTempPath(MAX_PATH, temp_path);
8549     SetCurrentDirectoryA(temp_path);
8550
8551     lstrcpyA(CURR_DIR, temp_path);
8552     len = lstrlenA(CURR_DIR);
8553
8554     if(len && (CURR_DIR[len - 1] == '\\'))
8555         CURR_DIR[len - 1] = 0;
8556
8557     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
8558
8559     /* Create a restore point ourselves so we circumvent the multitude of restore points
8560      * that would have been created by all the installation and removal tests.
8561      */
8562     if (pSRSetRestorePointA)
8563     {
8564         memset(&status, 0, sizeof(status));
8565         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
8566     }
8567
8568     /* Create only one log file and don't append. We have to pass something
8569      * for the log mode for this to work. The logfile needs to have an absolute
8570      * path otherwise we still end up with some extra logfiles as some tests
8571      * change the current directory.
8572      */
8573     lstrcpyA(log_file, temp_path);
8574     lstrcatA(log_file, "\\msitest.log");
8575     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
8576
8577     test_MsiInstallProduct();
8578     test_MsiSetComponentState();
8579     test_packagecoltypes();
8580     test_continuouscabs();
8581     test_caborder();
8582     test_mixedmedia();
8583     test_samesequence();
8584     test_uiLevelFlags();
8585     test_readonlyfile();
8586     test_readonlyfile_cab();
8587     test_setdirproperty();
8588     test_cabisextracted();
8589     test_concurrentinstall();
8590     test_setpropertyfolder();
8591     test_publish_registerproduct();
8592     test_publish_publishproduct();
8593     test_publish_publishfeatures();
8594     test_publish_registeruser();
8595     test_publish_processcomponents();
8596     test_publish();
8597     test_publishsourcelist();
8598     test_transformprop();
8599     test_currentworkingdir();
8600     test_admin();
8601     test_adminprops();
8602     test_removefiles();
8603     test_movefiles();
8604     test_missingcab();
8605     test_duplicatefiles();
8606     test_writeregistryvalues();
8607     test_sourcefolder();
8608     test_customaction51();
8609     test_installstate();
8610     test_sourcepath();
8611     test_MsiConfigureProductEx();
8612     test_missingcomponent();
8613     test_sourcedirprop();
8614     test_adminimage();
8615     test_propcase();
8616     test_int_widths();
8617     test_shortcut();
8618     test_envvar();
8619     test_lastusedsource();
8620     test_preselected();
8621     test_installed_prop();
8622     test_file_in_use();
8623     test_file_in_use_cab();
8624     test_MsiSetExternalUI();
8625     test_allusers_prop();
8626     test_feature_override();
8627     test_create_folder();
8628     test_remove_folder();
8629     test_start_services();
8630     test_delete_services();
8631     test_self_registration();
8632     test_register_font();
8633     test_validate_product_id();
8634     test_install_remove_odbc();
8635     test_register_typelib();
8636     test_create_remove_shortcut();
8637     test_publish_components();
8638     test_remove_duplicate_files();
8639     test_remove_registry_values();
8640
8641     DeleteFileA(log_file);
8642
8643     if (pSRSetRestorePointA && ret)
8644     {
8645         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
8646         if (ret)
8647             remove_restore_point(status.llSequenceNumber);
8648     }
8649     FreeLibrary(hsrclient);
8650
8651     SetCurrentDirectoryA(prev_path);
8652 }