msi: Add tests for registering and unregistering extension info.
[wine] / dlls / msi / tests / install.c
1 /*
2  * Copyright (C) 2006 James Hawkins
3  *
4  * A test program for installing MSI products.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22 #define COBJMACROS
23
24 #include <stdio.h>
25
26 #include <windows.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <msi.h>
30 #include <fci.h>
31 #include <objidl.h>
32 #include <srrestoreptapi.h>
33
34 #include "wine/test.h"
35
36 static UINT (WINAPI *pMsiQueryComponentStateA)
37     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
38 static UINT (WINAPI *pMsiSetExternalUIRecord)
39     (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
40 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiSourceListGetInfoA)
43     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
44
45 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
46
47 static HMODULE hsrclient = 0;
48 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
49 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
50
51 static BOOL on_win9x = FALSE;
52
53 static const char *msifile = "msitest.msi";
54 static const char *msifile2 = "winetest2.msi";
55 static const char *mstfile = "winetest.mst";
56 static CHAR CURR_DIR[MAX_PATH];
57 static CHAR PROG_FILES_DIR[MAX_PATH];
58 static CHAR COMMON_FILES_DIR[MAX_PATH];
59
60 /* msi database data */
61
62 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
63                                     "s72\tS38\ts72\ti2\tS255\tS72\n"
64                                     "Component\tComponent\n"
65                                     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
66                                     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
67                                     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
68                                     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
69                                     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
70                                     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
71                                     "component\t\tMSITESTDIR\t0\t1\tfile\n"
72                                     "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
73
74 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
75                                     "s72\tS72\tl255\n"
76                                     "Directory\tDirectory\n"
77                                     "CABOUTDIR\tMSITESTDIR\tcabout\n"
78                                     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
79                                     "FIRSTDIR\tMSITESTDIR\tfirst\n"
80                                     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
81                                     "NEWDIR\tCABOUTDIR\tnew\n"
82                                     "ProgramFilesFolder\tTARGETDIR\t.\n"
83                                     "TARGETDIR\t\tSourceDir";
84
85 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
86                                   "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
87                                   "Feature\tFeature\n"
88                                   "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
89                                   "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
90                                   "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
91                                   "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
92                                   "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
93                                   "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
94                                   "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
95
96 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
97                                        "s38\ts72\n"
98                                        "FeatureComponents\tFeature_\tComponent_\n"
99                                        "Five\tFive\n"
100                                        "Four\tFour\n"
101                                        "One\tOne\n"
102                                        "Three\tThree\n"
103                                        "Two\tTwo\n"
104                                        "feature\tcomponent\n"
105                                        "service_feature\tservice_comp\n";
106
107 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
108                                "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
109                                "File\tFile\n"
110                                "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
111                                "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
112                                "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
113                                "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
114                                "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
115                                "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
116                                "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
117
118 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
119                                            "s72\tS255\tI2\n"
120                                            "InstallExecuteSequence\tAction\n"
121                                            "AllocateRegistrySpace\tNOT Installed\t1550\n"
122                                            "CostFinalize\t\t1000\n"
123                                            "CostInitialize\t\t800\n"
124                                            "FileCost\t\t900\n"
125                                            "ResolveSource\t\t950\n"
126                                            "MoveFiles\t\t1700\n"
127                                            "InstallFiles\t\t4000\n"
128                                            "DuplicateFiles\t\t4500\n"
129                                            "WriteEnvironmentStrings\t\t4550\n"
130                                            "CreateShortcuts\t\t4600\n"
131                                            "InstallServices\t\t5000\n"
132                                            "InstallFinalize\t\t6600\n"
133                                            "InstallInitialize\t\t1500\n"
134                                            "InstallValidate\t\t1400\n"
135                                            "LaunchConditions\t\t100\n"
136                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
137
138 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
139                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
140                                 "Media\tDiskId\n"
141                                 "1\t3\t\t\tDISK1\t\n"
142                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
143
144 static const CHAR property_dat[] = "Property\tValue\n"
145                                    "s72\tl0\n"
146                                    "Property\tProperty\n"
147                                    "DefaultUIFont\tDlgFont8\n"
148                                    "HASUIRUN\t0\n"
149                                    "INSTALLLEVEL\t3\n"
150                                    "InstallMode\tTypical\n"
151                                    "Manufacturer\tWine\n"
152                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
153                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
154                                    "ProductID\tnone\n"
155                                    "ProductLanguage\t1033\n"
156                                    "ProductName\tMSITEST\n"
157                                    "ProductVersion\t1.1.1\n"
158                                    "PROMPTROLLBACKCOST\tP\n"
159                                    "Setup\tSetup\n"
160                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
161                                    "AdminProperties\tPOSTADMIN\n"
162                                    "ROOTDRIVE\tC:\\\n"
163                                    "SERVNAME\tTestService\n"
164                                    "SERVDISP\tTestServiceDisp\n";
165
166 static const CHAR aup_property_dat[] = "Property\tValue\n"
167                                        "s72\tl0\n"
168                                        "Property\tProperty\n"
169                                        "DefaultUIFont\tDlgFont8\n"
170                                        "HASUIRUN\t0\n"
171                                        "ALLUSERS\t1\n"
172                                        "INSTALLLEVEL\t3\n"
173                                        "InstallMode\tTypical\n"
174                                        "Manufacturer\tWine\n"
175                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
176                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
177                                        "ProductID\tnone\n"
178                                        "ProductLanguage\t1033\n"
179                                        "ProductName\tMSITEST\n"
180                                        "ProductVersion\t1.1.1\n"
181                                        "PROMPTROLLBACKCOST\tP\n"
182                                        "Setup\tSetup\n"
183                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
184                                        "AdminProperties\tPOSTADMIN\n"
185                                        "ROOTDRIVE\tC:\\\n"
186                                        "SERVNAME\tTestService\n"
187                                        "SERVDISP\tTestServiceDisp\n";
188
189 static const CHAR aup2_property_dat[] = "Property\tValue\n"
190                                         "s72\tl0\n"
191                                         "Property\tProperty\n"
192                                         "DefaultUIFont\tDlgFont8\n"
193                                         "HASUIRUN\t0\n"
194                                         "ALLUSERS\t2\n"
195                                         "INSTALLLEVEL\t3\n"
196                                         "InstallMode\tTypical\n"
197                                         "Manufacturer\tWine\n"
198                                         "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
199                                         "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
200                                         "ProductID\tnone\n"
201                                         "ProductLanguage\t1033\n"
202                                         "ProductName\tMSITEST\n"
203                                         "ProductVersion\t1.1.1\n"
204                                         "PROMPTROLLBACKCOST\tP\n"
205                                         "Setup\tSetup\n"
206                                         "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
207                                         "AdminProperties\tPOSTADMIN\n"
208                                         "ROOTDRIVE\tC:\\\n"
209                                         "SERVNAME\tTestService\n"
210                                         "SERVDISP\tTestServiceDisp\n";
211
212 static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
213                                    "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
214                                    "Shortcut\tShortcut\n"
215                                    "Shortcut\tMSITESTDIR\tShortcut\tcomponent\tShortcut\t\tShortcut\t\t\t\t\t\n";
216
217 static const CHAR environment_dat[] = "Environment\tName\tValue\tComponent_\n"
218                                       "s72\tl255\tL255\ts72\n"
219                                       "Environment\tEnvironment\n"
220                                       "Var1\t=-MSITESTVAR1\t1\tOne\n"
221                                       "Var2\tMSITESTVAR2\t1\tOne\n"
222                                       "Var3\t=-MSITESTVAR3\t1\tOne\n"
223                                       "Var4\tMSITESTVAR4\t1\tOne\n"
224                                       "Var5\t-MSITESTVAR5\t\tOne\n"
225                                       "Var6\tMSITESTVAR6\t\tOne\n"
226                                       "Var7\t!-MSITESTVAR7\t\tOne\n"
227                                       "Var8\t!-*MSITESTVAR8\t\tOne\n"
228                                       "Var9\t=-MSITESTVAR9\t\tOne\n"
229                                       "Var10\t=MSITESTVAR10\t\tOne\n"
230                                       "Var11\t+-MSITESTVAR11\t[~];1\tOne\n"
231                                       "Var12\t+-MSITESTVAR11\t[~];2\tOne\n"
232                                       "Var13\t+-MSITESTVAR12\t[~];1\tOne\n"
233                                       "Var14\t=MSITESTVAR13\t[~];1\tOne\n"
234                                       "Var15\t=MSITESTVAR13\t[~];2\tOne\n"
235                                       "Var16\t=MSITESTVAR14\t;1;\tOne\n"
236                                       "Var17\t=MSITESTVAR15\t;;1;;\tOne\n"
237                                       "Var18\t=MSITESTVAR16\t 1 \tOne\n"
238                                       "Var19\t+-MSITESTVAR17\t1\tOne\n"
239                                       "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n"
240                                       "Var21\t+-MSITESTVAR18\t1\tOne\n"
241                                       "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n"
242                                       "Var23\t+-MSITESTVAR19\t1\tOne\n"
243                                       "Var24\t+-MSITESTVAR19\t[~]2\tOne\n"
244                                       "Var25\t+-MSITESTVAR20\t1\tOne\n"
245                                       "Var26\t+-MSITESTVAR20\t2[~]\tOne\n";
246
247 /* Expected results, starting from MSITESTVAR11 onwards */
248 static const CHAR *environment_dat_results[] = {"1;2",    /*MSITESTVAR11*/
249                                                 "1",      /*MSITESTVAR12*/
250                                                 "1;2",    /*MSITESTVAR13*/
251                                                 ";1;",    /*MSITESTVAR14*/
252                                                 ";;1;;",  /*MSITESTVAR15*/
253                                                 " 1 ",    /*MSITESTVAR16*/
254                                                 ";;2;;1", /*MSITESTVAR17*/
255                                                 "1;;2;;", /*MSITESTVAR18*/
256                                                 "1",      /*MSITESTVAR19*/
257                                                 "1",      /*MSITESTVAR20*/
258                                                 NULL};
259
260 static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n"
261                                     "s38\ti2\tS255\n"
262                                     "Condition\tFeature_\tLevel\n"
263                                     "One\t4\t1\n";
264
265 static const CHAR up_property_dat[] = "Property\tValue\n"
266                                       "s72\tl0\n"
267                                       "Property\tProperty\n"
268                                       "DefaultUIFont\tDlgFont8\n"
269                                       "HASUIRUN\t0\n"
270                                       "INSTALLLEVEL\t3\n"
271                                       "InstallMode\tTypical\n"
272                                       "Manufacturer\tWine\n"
273                                       "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
274                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
275                                       "ProductID\tnone\n"
276                                       "ProductLanguage\t1033\n"
277                                       "ProductName\tMSITEST\n"
278                                       "ProductVersion\t1.1.1\n"
279                                       "PROMPTROLLBACKCOST\tP\n"
280                                       "Setup\tSetup\n"
281                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
282                                       "AdminProperties\tPOSTADMIN\n"
283                                       "ROOTDRIVE\tC:\\\n"
284                                       "SERVNAME\tTestService\n"
285                                       "SERVDISP\tTestServiceDisp\n"
286                                       "RemovePreviousVersions\t1\n";
287
288 static const CHAR up2_property_dat[] = "Property\tValue\n"
289                                        "s72\tl0\n"
290                                        "Property\tProperty\n"
291                                        "DefaultUIFont\tDlgFont8\n"
292                                        "HASUIRUN\t0\n"
293                                        "INSTALLLEVEL\t3\n"
294                                        "InstallMode\tTypical\n"
295                                        "Manufacturer\tWine\n"
296                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
297                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
298                                        "ProductID\tnone\n"
299                                        "ProductLanguage\t1033\n"
300                                        "ProductName\tMSITEST\n"
301                                        "ProductVersion\t1.1.2\n"
302                                        "PROMPTROLLBACKCOST\tP\n"
303                                        "Setup\tSetup\n"
304                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
305                                        "AdminProperties\tPOSTADMIN\n"
306                                        "ROOTDRIVE\tC:\\\n"
307                                        "SERVNAME\tTestService\n"
308                                        "SERVDISP\tTestServiceDisp\n";
309
310 static const CHAR up3_property_dat[] = "Property\tValue\n"
311                                        "s72\tl0\n"
312                                        "Property\tProperty\n"
313                                        "DefaultUIFont\tDlgFont8\n"
314                                        "HASUIRUN\t0\n"
315                                        "INSTALLLEVEL\t3\n"
316                                        "InstallMode\tTypical\n"
317                                        "Manufacturer\tWine\n"
318                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
319                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
320                                        "ProductID\tnone\n"
321                                        "ProductLanguage\t1033\n"
322                                        "ProductName\tMSITEST\n"
323                                        "ProductVersion\t1.1.2\n"
324                                        "PROMPTROLLBACKCOST\tP\n"
325                                        "Setup\tSetup\n"
326                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
327                                        "AdminProperties\tPOSTADMIN\n"
328                                        "ROOTDRIVE\tC:\\\n"
329                                        "SERVNAME\tTestService\n"
330                                        "SERVDISP\tTestServiceDisp\n"
331                                        "RemovePreviousVersions\t1\n";
332
333 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
334                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
335                                    "Registry\tRegistry\n"
336                                    "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
337                                    "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
338                                    "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
339                                    "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
340
341 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
342                                           "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
343                                           "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
344                                           "ServiceInstall\tServiceInstall\n"
345                                           "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
346
347 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
348                                           "s72\tl255\ti2\tL255\tI2\ts72\n"
349                                           "ServiceControl\tServiceControl\n"
350                                           "ServiceControl\tTestService\t8\t\t0\tservice_comp";
351
352 static const CHAR sss_service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
353                                               "s72\tl255\ti2\tL255\tI2\ts72\n"
354                                               "ServiceControl\tServiceControl\n"
355                                               "ServiceControl\tSpooler\t1\t\t0\tservice_comp";
356
357 static const CHAR sss_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
358                                                "s72\tS255\tI2\n"
359                                                "InstallExecuteSequence\tAction\n"
360                                                "CostFinalize\t\t1000\n"
361                                                "CostInitialize\t\t800\n"
362                                                "FileCost\t\t900\n"
363                                                "ResolveSource\t\t950\n"
364                                                "MoveFiles\t\t1700\n"
365                                                "InstallFiles\t\t4000\n"
366                                                "DuplicateFiles\t\t4500\n"
367                                                "WriteEnvironmentStrings\t\t4550\n"
368                                                "CreateShortcuts\t\t4600\n"
369                                                "StartServices\t\t5000\n"
370                                                "DeleteServices\t\t5500\n"
371                                                "InstallFinalize\t\t6600\n"
372                                                "InstallInitialize\t\t1500\n"
373                                                "InstallValidate\t\t1400\n"
374                                                "LaunchConditions\t\t100\n";
375
376 /* tables for test_continuouscabs */
377 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
378                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
379                                        "Component\tComponent\n"
380                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
381                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
382                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
383
384 static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
385                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
386                                         "Component\tComponent\n"
387                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
388                                         "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
389                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
390
391 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
392                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
393                                      "Feature\tFeature\n"
394                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
395
396 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
397                                           "s38\ts72\n"
398                                           "FeatureComponents\tFeature_\tComponent_\n"
399                                           "feature\tmaximus\n"
400                                           "feature\taugustus\n"
401                                           "feature\tcaesar";
402
403 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
404                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
405                                   "File\tFile\n"
406                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
407                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
408                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
409
410 static const CHAR cc2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
411                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
412                                    "File\tFile\n"
413                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
414                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
415                                    "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
416                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
417
418 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
419                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
420                                    "Media\tDiskId\n"
421                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
422                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
423                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
424
425 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
426                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
427                                   "File\tFile\n"
428                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
429                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
430                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
431
432 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
433                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
434                                    "Media\tDiskId\n"
435                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
436                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
437                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
438
439 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
440                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
441                                     "Media\tDiskId\n"
442                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
443                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
444                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
445
446 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
447                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
448                                   "File\tFile\n"
449                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
450                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
451                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
452
453 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
454                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
455                                    "Media\tDiskId\n"
456                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
457
458 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
459                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
460                                    "Media\tDiskId\n"
461                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
462                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
463                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
464
465 /* tables for test_uiLevelFlags */
466 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
467                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
468                                        "Component\tComponent\n"
469                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
470                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
471                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
472
473 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
474                                            "s72\tS255\tI2\n"
475                                            "InstallUISequence\tAction\n"
476                                            "SetUIProperty\t\t5\n"
477                                            "ExecuteAction\t\t1100\n";
478
479 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
480                                            "s72\ti2\tS64\tS0\tS255\n"
481                                            "CustomAction\tAction\n"
482                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
483
484 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
485                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
486                                         "Component\tComponent\n"
487                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
488
489 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
490                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
491                                       "Feature\tFeature\n"
492                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
493                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
494
495 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
496                                            "s38\ts72\n"
497                                            "FeatureComponents\tFeature_\tComponent_\n"
498                                            "feature\tmaximus\n"
499                                            "montecristo\tmaximus";
500
501 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
502                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
503                                    "File\tFile\n"
504                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
505
506 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
507                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
508                                     "Media\tDiskId\n"
509                                     "1\t1\t\t\tDISK1\t\n";
510
511 static const CHAR rofc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
512                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
513                                     "File\tFile\n"
514                                     "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1";
515
516 static const CHAR rofc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
517                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
518                                      "Media\tDiskId\n"
519                                      "1\t1\t\ttest1.cab\tDISK1\t\n";
520
521 static const CHAR lus2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
522                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
523                                      "Media\tDiskId\n"
524                                      "1\t1\t\t#test1.cab\tDISK1\t\n";
525
526 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
527                                                "s72\tS255\tI2\n"
528                                                "InstallExecuteSequence\tAction\n"
529                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
530                                                "CostFinalize\t\t1000\n"
531                                                "CostInitialize\t\t800\n"
532                                                "FileCost\t\t900\n"
533                                                "InstallFiles\t\t4000\n"
534                                                "InstallFinalize\t\t6600\n"
535                                                "InstallInitialize\t\t1500\n"
536                                                "InstallValidate\t\t1400\n"
537                                                "LaunchConditions\t\t100\n"
538                                                "SetDirProperty\t\t950";
539
540 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
541                                             "s72\ti2\tS64\tS0\tS255\n"
542                                             "CustomAction\tAction\n"
543                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
544
545 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
546                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
547                                         "Component\tComponent\n"
548                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
549                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
550                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
551                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
552
553 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
554                                            "s38\ts72\n"
555                                            "FeatureComponents\tFeature_\tComponent_\n"
556                                            "feature\tmaximus\n"
557                                            "feature\taugustus\n"
558                                            "feature\tcaesar\n"
559                                            "feature\tgaius";
560
561 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
562                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
563                                    "File\tFile\n"
564                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
565                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
566                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
567                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
568
569 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
570                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
571                                     "Media\tDiskId\n"
572                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
573                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
574                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
575
576 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
577                                               "s72\tS255\tI2\n"
578                                               "InstallExecuteSequence\tAction\n"
579                                               "CostFinalize\t\t1000\n"
580                                               "CostInitialize\t\t800\n"
581                                               "FileCost\t\t900\n"
582                                               "InstallFiles\t\t4000\n"
583                                               "InstallServices\t\t5000\n"
584                                               "InstallFinalize\t\t6600\n"
585                                               "InstallInitialize\t\t1500\n"
586                                               "RunInstall\t\t1600\n"
587                                               "InstallValidate\t\t1400\n"
588                                               "LaunchConditions\t\t100";
589
590 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
591                                             "s72\ti2\tS64\tS0\tS255\n"
592                                             "CustomAction\tAction\n"
593                                             "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
594
595 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
596                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
597                                        "Component\tComponent\n"
598                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
599
600 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
601                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
602                                         "Component\tComponent\n"
603                                         "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
604
605 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
606                                            "s38\ts72\n"
607                                            "FeatureComponents\tFeature_\tComponent_\n"
608                                            "feature\taugustus";
609
610 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
611                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
612                                    "File\tFile\n"
613                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
614
615 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
616                                             "s72\ti2\tS64\tS0\tS255\n"
617                                             "CustomAction\tAction\n"
618                                             "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
619
620 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
621                                                "s72\tS255\tI2\n"
622                                                "InstallExecuteSequence\tAction\n"
623                                                "CostFinalize\t\t1000\n"
624                                                "CostInitialize\t\t800\n"
625                                                "FileCost\t\t900\n"
626                                                "SetFolderProp\t\t950\n"
627                                                "InstallFiles\t\t4000\n"
628                                                "InstallServices\t\t5000\n"
629                                                "InstallFinalize\t\t6600\n"
630                                                "InstallInitialize\t\t1500\n"
631                                                "InstallValidate\t\t1400\n"
632                                                "LaunchConditions\t\t100";
633
634 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
635                                              "s72\tS255\tI2\n"
636                                              "InstallUISequence\tAction\n"
637                                              "CostInitialize\t\t800\n"
638                                              "FileCost\t\t900\n"
639                                              "CostFinalize\t\t1000\n"
640                                              "ExecuteAction\t\t1100\n";
641
642 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
643                                               "s72\tS255\tI2\n"
644                                               "InstallExecuteSequence\tAction\n"
645                                               "ValidateProductID\t\t700\n"
646                                               "CostInitialize\t\t800\n"
647                                               "FileCost\t\t900\n"
648                                               "CostFinalize\t\t1000\n"
649                                               "InstallValidate\t\t1400\n"
650                                               "InstallInitialize\t\t1500\n"
651                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
652                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
653                                               "RemoveFiles\t\t3500\n"
654                                               "InstallFiles\t\t4000\n"
655                                               "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
656                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
657                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
658                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
659                                               "InstallFinalize\t\t6600";
660
661 static const CHAR ppc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
662                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
663                                         "Component\tComponent\n"
664                                         "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n"
665                                         "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n";
666
667 static const CHAR ppc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
668                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
669                                    "File\tFile\n"
670                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n"
671                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t2";
672
673 static const CHAR ppc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
674                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
675                                     "Media\tDiskId\n"
676                                     "1\t2\t\t\tDISK1\t\n";
677
678 static const CHAR ppc_feature_comp_dat[] = "Feature_\tComponent_\n"
679                                            "s38\ts72\n"
680                                            "FeatureComponents\tFeature_\tComponent_\n"
681                                            "feature\tmaximus\n"
682                                            "feature\taugustus\n"
683                                            "montecristo\tmaximus";
684
685 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
686                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
687                                        "Component\tComponent\n"
688                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
689
690 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
691                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
692                                         "Component\tComponent\n"
693                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
694
695 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
696                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
697                                         "Component\tComponent\n"
698                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
699
700 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
701                                             "s72\ti2\tS64\tS0\tS255\n"
702                                             "CustomAction\tAction\n"
703                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
704
705 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
706                                              "s72\tS255\tI2\n"
707                                              "AdminExecuteSequence\tAction\n"
708                                              "CostFinalize\t\t1000\n"
709                                              "CostInitialize\t\t800\n"
710                                              "FileCost\t\t900\n"
711                                              "SetPOSTADMIN\t\t950\n"
712                                              "InstallFiles\t\t4000\n"
713                                              "InstallFinalize\t\t6600\n"
714                                              "InstallInitialize\t\t1500\n"
715                                              "InstallValidate\t\t1400\n"
716                                              "LaunchConditions\t\t100";
717
718 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
719                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
720                                         "Component\tComponent\n"
721                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718 and MyProp=42\taugustus\n";
722
723 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
724                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
725                                         "Component\tComponent\n"
726                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
727                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
728                                         "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
729
730 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
731                                            "s38\ts72\n"
732                                            "FeatureComponents\tFeature_\tComponent_\n"
733                                            "feature\thydrogen\n"
734                                            "feature\thelium\n"
735                                            "feature\tlithium";
736
737 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
738                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
739                                    "File\tFile\n"
740                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
741                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
742                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
743
744 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
745                                                "s72\tS255\tI2\n"
746                                                "InstallExecuteSequence\tAction\n"
747                                                "ValidateProductID\t\t700\n"
748                                                "CostInitialize\t\t800\n"
749                                                "FileCost\t\t900\n"
750                                                "CostFinalize\t\t1000\n"
751                                                "InstallValidate\t\t1400\n"
752                                                "InstallInitialize\t\t1500\n"
753                                                "ProcessComponents\t\t1600\n"
754                                                "UnpublishFeatures\t\t1800\n"
755                                                "RemoveFiles\t\t3500\n"
756                                                "InstallFiles\t\t4000\n"
757                                                "RegisterProduct\t\t6100\n"
758                                                "PublishFeatures\t\t6300\n"
759                                                "PublishProduct\t\t6400\n"
760                                                "InstallFinalize\t\t6600";
761
762 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
763                                            "s72\ts72\tS255\ts72\tI2\n"
764                                            "RemoveFile\tFileKey\n"
765                                            "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
766                                            "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
767                                            "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
768                                            "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
769                                            "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
770                                            "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
771                                            "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
772                                            "block\thelium\tblock\tMSITESTDIR\t3\n"
773                                            "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n"
774                                            "nanoacre\thydrogen\t\tCABOUTDIR\t3\n";
775
776 static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
777                                         "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
778                                         "MoveFile\tFileKey\n"
779                                         "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
780                                         "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
781                                         "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
782                                         "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
783                                         "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
784                                         "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
785                                         "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
786                                         "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
787                                         "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
788                                         "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
789                                         "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
790                                         "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
791                                         "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
792                                         "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n"
793                                         "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
794                                         "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
795                                         "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
796                                         "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
797
798 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
799                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
800                                         "Component\tComponent\n"
801                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
802                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
803                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
804                                         "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
805
806 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
807                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
808                                   "File\tFile\n"
809                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
810                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
811                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
812                                   "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
813
814 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
815                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
816                                    "Media\tDiskId\n"
817                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
818                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
819                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
820                                    "4\t4\t\ttest3.cab\tDISK3\t\n";
821
822 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
823                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
824                                        "MsiFileHash\tFile_\n"
825                                        "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
826
827 static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
828                                        "s72\tS72\tl255\n"
829                                        "Directory\tDirectory\n"
830                                        "THIS\tMSITESTDIR\tthis\n"
831                                        "DOESNOT\tTHIS\tdoesnot\n"
832                                        "NONEXISTENT\tDOESNOT\texist\n"
833                                        "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
834                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
835                                        "TARGETDIR\t\tSourceDir";
836
837 static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
838                                             "s72\ts72\ts72\tS255\tS72\n"
839                                             "DuplicateFile\tFileKey\n"
840                                             "maximus\tmaximus\tmaximus\taugustus\t\n"
841                                             "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n"
842                                             "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n";
843
844 static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
845                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
846                                         "Component\tComponent\n"
847                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
848
849 static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
850                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
851                                        "Registry\tRegistry\n"
852                                        "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
853
854 static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
855                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
856                                          "Component\tComponent\n"
857                                          "augustus\t\tMSITESTDIR\t0\tMYPROP=42\taugustus\n";
858
859 static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
860                                                 "s72\tS255\tI2\n"
861                                                 "InstallExecuteSequence\tAction\n"
862                                                 "ValidateProductID\t\t700\n"
863                                                 "GoodSetProperty\t\t725\n"
864                                                 "BadSetProperty\t\t750\n"
865                                                 "CostInitialize\t\t800\n"
866                                                 "ResolveSource\t\t810\n"
867                                                 "FileCost\t\t900\n"
868                                                 "SetSourceDir\tSRCDIR\t910\n"
869                                                 "CostFinalize\t\t1000\n"
870                                                 "InstallValidate\t\t1400\n"
871                                                 "InstallInitialize\t\t1500\n"
872                                                 "InstallFiles\t\t4000\n"
873                                                 "InstallFinalize\t\t6600";
874
875 static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
876                                              "s72\ti2\tS64\tS0\n"
877                                              "CustomAction\tAction\n"
878                                              "GoodSetProperty\t51\tMYPROP\t42\n"
879                                              "BadSetProperty\t51\t\tMYPROP\n"
880                                              "SetSourceDir\t51\tSourceDir\t[SRCDIR]\n";
881
882 static const CHAR is_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
883                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
884                                      "Feature\tFeature\n"
885                                      "one\t\t\t\t2\t1\t\t0\n" /* favorLocal */
886                                      "two\t\t\t\t2\t1\t\t1\n" /* favorSource */
887                                      "three\t\t\t\t2\t1\t\t4\n" /* favorAdvertise */
888                                      "four\t\t\t\t2\t0\t\t0"; /* disabled */
889
890 static const CHAR is_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
891                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
892                                        "Component\tComponent\n"
893                                        "alpha\t\tMSITESTDIR\t0\t\talpha_file\n" /* favorLocal:Local */
894                                        "beta\t\tMSITESTDIR\t1\t\tbeta_file\n" /* favorLocal:Source */
895                                        "gamma\t\tMSITESTDIR\t2\t\tgamma_file\n" /* favorLocal:Optional */
896                                        "theta\t\tMSITESTDIR\t0\t\ttheta_file\n" /* favorSource:Local */
897                                        "delta\t\tMSITESTDIR\t1\t\tdelta_file\n" /* favorSource:Source */
898                                        "epsilon\t\tMSITESTDIR\t2\t\tepsilon_file\n" /* favorSource:Optional */
899                                        "zeta\t\tMSITESTDIR\t0\t\tzeta_file\n" /* favorAdvertise:Local */
900                                        "iota\t\tMSITESTDIR\t1\t\tiota_file\n" /* favorAdvertise:Source */
901                                        "eta\t\tMSITESTDIR\t2\t\teta_file\n" /* favorAdvertise:Optional */
902                                        "kappa\t\tMSITESTDIR\t0\t\tkappa_file\n" /* disabled:Local */
903                                        "lambda\t\tMSITESTDIR\t1\t\tlambda_file\n" /* disabled:Source */
904                                        "mu\t\tMSITESTDIR\t2\t\tmu_file\n"; /* disabled:Optional */
905
906 static const CHAR is_feature_comp_dat[] = "Feature_\tComponent_\n"
907                                           "s38\ts72\n"
908                                           "FeatureComponents\tFeature_\tComponent_\n"
909                                           "one\talpha\n"
910                                           "one\tbeta\n"
911                                           "one\tgamma\n"
912                                           "two\ttheta\n"
913                                           "two\tdelta\n"
914                                           "two\tepsilon\n"
915                                           "three\tzeta\n"
916                                           "three\tiota\n"
917                                           "three\teta\n"
918                                           "four\tkappa\n"
919                                           "four\tlambda\n"
920                                           "four\tmu";
921
922 static const CHAR is_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
923                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
924                                   "File\tFile\n"
925                                   "alpha_file\talpha\talpha\t500\t\t\t8192\t1\n"
926                                   "beta_file\tbeta\tbeta\t500\t\t\t8291\t2\n"
927                                   "gamma_file\tgamma\tgamma\t500\t\t\t8192\t3\n"
928                                   "theta_file\ttheta\ttheta\t500\t\t\t8192\t4\n"
929                                   "delta_file\tdelta\tdelta\t500\t\t\t8192\t5\n"
930                                   "epsilon_file\tepsilon\tepsilon\t500\t\t\t8192\t6\n"
931                                   "zeta_file\tzeta\tzeta\t500\t\t\t8192\t7\n"
932                                   "iota_file\tiota\tiota\t500\t\t\t8192\t8\n"
933                                   "eta_file\teta\teta\t500\t\t\t8192\t9\n"
934                                   "kappa_file\tkappa\tkappa\t500\t\t\t8192\t10\n"
935                                   "lambda_file\tlambda\tlambda\t500\t\t\t8192\t11\n"
936                                   "mu_file\tmu\tmu\t500\t\t\t8192\t12";
937
938 static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
939                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
940                                    "Media\tDiskId\n"
941                                    "1\t12\t\t\tDISK1\t\n";
942
943 static const CHAR sp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
944                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
945                                         "Component\tComponent\n"
946                                         "augustus\t\tTWODIR\t0\t\taugustus\n";
947
948 static const CHAR sp_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
949                                        "s72\tS72\tl255\n"
950                                        "Directory\tDirectory\n"
951                                        "TARGETDIR\t\tSourceDir\n"
952                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
953                                        "MSITESTDIR\tProgramFilesFolder\tmsitest:.\n"
954                                        "ONEDIR\tMSITESTDIR\t.:shortone|longone\n"
955                                        "TWODIR\tONEDIR\t.:shorttwo|longtwo";
956
957 static const CHAR mcp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
958                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
959                                         "Component\tComponent\n"
960                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
961                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
962                                         "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
963
964 static const CHAR mcp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
965                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
966                                       "Feature\tFeature\n"
967                                       "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
968                                       "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
969                                       "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
970
971 static const CHAR mcp_feature_comp_dat[] = "Feature_\tComponent_\n"
972                                            "s38\ts72\n"
973                                            "FeatureComponents\tFeature_\tComponent_\n"
974                                            "hydroxyl\thydrogen\n"
975                                            "heliox\thelium\n"
976                                            "lithia\tlithium";
977
978 static const CHAR mcomp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
979                                      "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
980                                      "File\tFile\n"
981                                      "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
982                                      "helium\thelium\thelium\t0\t\t\t8192\t1\n"
983                                      "lithium\tlithium\tlithium\t0\t\t\t8192\t1\n"
984                                      "beryllium\tmissingcomp\tberyllium\t0\t\t\t8192\t1";
985
986 static const CHAR ai_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
987                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
988                                   "File\tFile\n"
989                                   "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
990                                   "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
991                                   "one.txt\tOne\tone.txt\t1000\t\t\t16384\t1\n"
992                                   "three.txt\tThree\tthree.txt\t1000\t\t\t16384\t3\n"
993                                   "two.txt\tTwo\ttwo.txt\t1000\t\t\t16384\t2\n"
994                                   "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
995                                   "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
996
997 static const CHAR ip_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
998                                               "s72\tS255\tI2\n"
999                                               "InstallExecuteSequence\tAction\n"
1000                                               "CostFinalize\t\t1000\n"
1001                                               "ValidateProductID\t\t700\n"
1002                                               "CostInitialize\t\t800\n"
1003                                               "FileCost\t\t900\n"
1004                                               "RemoveFiles\t\t3500\n"
1005                                               "InstallFiles\t\t4000\n"
1006                                               "RegisterUser\t\t6000\n"
1007                                               "RegisterProduct\t\t6100\n"
1008                                               "PublishFeatures\t\t6300\n"
1009                                               "PublishProduct\t\t6400\n"
1010                                               "InstallFinalize\t\t6600\n"
1011                                               "InstallInitialize\t\t1500\n"
1012                                               "ProcessComponents\t\t1600\n"
1013                                               "UnpublishFeatures\t\t1800\n"
1014                                               "InstallValidate\t\t1400\n"
1015                                               "LaunchConditions\t\t100\n"
1016                                               "TestInstalledProp\tInstalled AND NOT REMOVE\t950\n";
1017
1018 static const CHAR ip_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1019                                            "s72\ti2\tS64\tS0\tS255\n"
1020                                            "CustomAction\tAction\n"
1021                                            "TestInstalledProp\t19\t\tTest failed\t\n";
1022
1023 static const CHAR aup_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1024                                                "s72\tS255\tI2\n"
1025                                                "InstallExecuteSequence\tAction\n"
1026                                                "CostFinalize\t\t1000\n"
1027                                                "ValidateProductID\t\t700\n"
1028                                                "CostInitialize\t\t800\n"
1029                                                "FileCost\t\t900\n"
1030                                                "RemoveFiles\t\t3500\n"
1031                                                "InstallFiles\t\t4000\n"
1032                                                "RegisterUser\t\t6000\n"
1033                                                "RegisterProduct\t\t6100\n"
1034                                                "PublishFeatures\t\t6300\n"
1035                                                "PublishProduct\t\t6400\n"
1036                                                "InstallFinalize\t\t6600\n"
1037                                                "InstallInitialize\t\t1500\n"
1038                                                "ProcessComponents\t\t1600\n"
1039                                                "UnpublishFeatures\t\t1800\n"
1040                                                "InstallValidate\t\t1400\n"
1041                                                "LaunchConditions\t\t100\n"
1042                                                "TestAllUsersProp\tALLUSERS AND NOT REMOVE\t50\n";
1043
1044 static const CHAR aup2_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1045                                                 "s72\tS255\tI2\n"
1046                                                 "InstallExecuteSequence\tAction\n"
1047                                                 "CostFinalize\t\t1000\n"
1048                                                 "ValidateProductID\t\t700\n"
1049                                                 "CostInitialize\t\t800\n"
1050                                                 "FileCost\t\t900\n"
1051                                                 "RemoveFiles\t\t3500\n"
1052                                                 "InstallFiles\t\t4000\n"
1053                                                 "RegisterUser\t\t6000\n"
1054                                                 "RegisterProduct\t\t6100\n"
1055                                                 "PublishFeatures\t\t6300\n"
1056                                                 "PublishProduct\t\t6400\n"
1057                                                 "InstallFinalize\t\t6600\n"
1058                                                 "InstallInitialize\t\t1500\n"
1059                                                 "ProcessComponents\t\t1600\n"
1060                                                 "UnpublishFeatures\t\t1800\n"
1061                                                 "InstallValidate\t\t1400\n"
1062                                                 "LaunchConditions\t\t100\n"
1063                                                 "TestAllUsersProp\tALLUSERS=2 AND NOT REMOVE\t50\n";
1064
1065 static const CHAR aup3_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1066                                                 "s72\tS255\tI2\n"
1067                                                 "InstallExecuteSequence\tAction\n"
1068                                                 "CostFinalize\t\t1000\n"
1069                                                 "ValidateProductID\t\t700\n"
1070                                                 "CostInitialize\t\t800\n"
1071                                                 "FileCost\t\t900\n"
1072                                                 "RemoveFiles\t\t3500\n"
1073                                                 "InstallFiles\t\t4000\n"
1074                                                 "RegisterUser\t\t6000\n"
1075                                                 "RegisterProduct\t\t6100\n"
1076                                                 "PublishFeatures\t\t6300\n"
1077                                                 "PublishProduct\t\t6400\n"
1078                                                 "InstallFinalize\t\t6600\n"
1079                                                 "InstallInitialize\t\t1500\n"
1080                                                 "ProcessComponents\t\t1600\n"
1081                                                 "UnpublishFeatures\t\t1800\n"
1082                                                 "InstallValidate\t\t1400\n"
1083                                                 "LaunchConditions\t\t100\n"
1084                                                 "TestAllUsersProp\tALLUSERS=1 AND NOT REMOVE\t50\n";
1085
1086 static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1087                                             "s72\ti2\tS64\tS0\tS255\n"
1088                                             "CustomAction\tAction\n"
1089                                             "TestAllUsersProp\t19\t\tTest failed\t\n";
1090
1091 static const CHAR cf_create_folders_dat[] = "Directory_\tComponent_\n"
1092                                             "s72\ts72\n"
1093                                             "CreateFolder\tDirectory_\tComponent_\n"
1094                                             "FIRSTDIR\tOne\n";
1095
1096 static const CHAR cf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1097                                               "s72\tS255\tI2\n"
1098                                               "InstallExecuteSequence\tAction\n"
1099                                               "CostFinalize\t\t1000\n"
1100                                               "ValidateProductID\t\t700\n"
1101                                               "CostInitialize\t\t800\n"
1102                                               "FileCost\t\t900\n"
1103                                               "RemoveFiles\t\t3500\n"
1104                                               "CreateFolders\t\t3700\n"
1105                                               "InstallExecute\t\t3800\n"
1106                                               "TestCreateFolders\t\t3900\n"
1107                                               "InstallFiles\t\t4000\n"
1108                                               "RegisterUser\t\t6000\n"
1109                                               "RegisterProduct\t\t6100\n"
1110                                               "PublishFeatures\t\t6300\n"
1111                                               "PublishProduct\t\t6400\n"
1112                                               "InstallFinalize\t\t6600\n"
1113                                               "InstallInitialize\t\t1500\n"
1114                                               "ProcessComponents\t\t1600\n"
1115                                               "UnpublishFeatures\t\t1800\n"
1116                                               "InstallValidate\t\t1400\n"
1117                                               "LaunchConditions\t\t100\n";
1118
1119 static const CHAR cf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1120                                            "s72\ti2\tS64\tS0\tS255\n"
1121                                            "CustomAction\tAction\n"
1122                                            "TestCreateFolders\t19\t\tHalts installation\t\n";
1123
1124 static const CHAR rf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1125                                               "s72\tS255\tI2\n"
1126                                               "InstallExecuteSequence\tAction\n"
1127                                               "CostFinalize\t\t1000\n"
1128                                               "ValidateProductID\t\t700\n"
1129                                               "CostInitialize\t\t800\n"
1130                                               "FileCost\t\t900\n"
1131                                               "RemoveFiles\t\t3500\n"
1132                                               "CreateFolders\t\t3600\n"
1133                                               "RemoveFolders\t\t3700\n"
1134                                               "InstallExecute\t\t3800\n"
1135                                               "TestCreateFolders\t\t3900\n"
1136                                               "InstallFiles\t\t4000\n"
1137                                               "RegisterUser\t\t6000\n"
1138                                               "RegisterProduct\t\t6100\n"
1139                                               "PublishFeatures\t\t6300\n"
1140                                               "PublishProduct\t\t6400\n"
1141                                               "InstallFinalize\t\t6600\n"
1142                                               "InstallInitialize\t\t1500\n"
1143                                               "ProcessComponents\t\t1600\n"
1144                                               "UnpublishFeatures\t\t1800\n"
1145                                               "InstallValidate\t\t1400\n"
1146                                               "LaunchConditions\t\t100\n";
1147
1148
1149 static const CHAR sr_selfreg_dat[] = "File_\tCost\n"
1150                                      "s72\tI2\n"
1151                                      "SelfReg\tFile_\n"
1152                                      "one.txt\t1\n";
1153
1154 static const CHAR sr_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1155                                               "s72\tS255\tI2\n"
1156                                               "InstallExecuteSequence\tAction\n"
1157                                               "CostFinalize\t\t1000\n"
1158                                               "CostInitialize\t\t800\n"
1159                                               "FileCost\t\t900\n"
1160                                               "ResolveSource\t\t950\n"
1161                                               "MoveFiles\t\t1700\n"
1162                                               "SelfUnregModules\t\t3900\n"
1163                                               "InstallFiles\t\t4000\n"
1164                                               "DuplicateFiles\t\t4500\n"
1165                                               "WriteEnvironmentStrings\t\t4550\n"
1166                                               "CreateShortcuts\t\t4600\n"
1167                                               "InstallFinalize\t\t6600\n"
1168                                               "InstallInitialize\t\t1500\n"
1169                                               "InstallValidate\t\t1400\n"
1170                                               "LaunchConditions\t\t100\n";
1171
1172 static const CHAR font_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
1173                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
1174                                      "Media\tDiskId\n"
1175                                      "1\t3\t\t\tDISK1\t\n";
1176
1177 static const CHAR font_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1178                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1179                                     "File\tFile\n"
1180                                     "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n";
1181
1182 static const CHAR font_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1183                                        "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1184                                        "Feature\tFeature\n"
1185                                        "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n";
1186
1187 static const CHAR font_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1188                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
1189                                          "Component\tComponent\n"
1190                                          "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n";
1191
1192 static const CHAR font_feature_comp_dat[] = "Feature_\tComponent_\n"
1193                                             "s38\ts72\n"
1194                                             "FeatureComponents\tFeature_\tComponent_\n"
1195                                             "fonts\tfonts\n";
1196
1197 static const CHAR font_dat[] = "File_\tFontTitle\n"
1198                                "s72\tS128\n"
1199                                "Font\tFile_\n"
1200                                "font.ttf\tmsi test font\n";
1201
1202 static const CHAR font_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1203                                                 "s72\tS255\tI2\n"
1204                                                 "InstallExecuteSequence\tAction\n"
1205                                                 "ValidateProductID\t\t700\n"
1206                                                 "CostInitialize\t\t800\n"
1207                                                 "FileCost\t\t900\n"
1208                                                 "CostFinalize\t\t1000\n"
1209                                                 "InstallValidate\t\t1400\n"
1210                                                 "InstallInitialize\t\t1500\n"
1211                                                 "ProcessComponents\t\t1600\n"
1212                                                 "UnpublishFeatures\t\t1800\n"
1213                                                 "RemoveFiles\t\t3500\n"
1214                                                 "InstallFiles\t\t4000\n"
1215                                                 "RegisterFonts\t\t4100\n"
1216                                                 "UnregisterFonts\t\t4200\n"
1217                                                 "RegisterUser\t\t6000\n"
1218                                                 "RegisterProduct\t\t6100\n"
1219                                                 "PublishFeatures\t\t6300\n"
1220                                                 "PublishProduct\t\t6400\n"
1221                                                 "InstallFinalize\t\t6600";
1222
1223 static const CHAR vp_property_dat[] = "Property\tValue\n"
1224                                       "s72\tl0\n"
1225                                       "Property\tProperty\n"
1226                                       "HASUIRUN\t0\n"
1227                                       "INSTALLLEVEL\t3\n"
1228                                       "InstallMode\tTypical\n"
1229                                       "Manufacturer\tWine\n"
1230                                       "PIDTemplate\t###-#######\n"
1231                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
1232                                       "ProductLanguage\t1033\n"
1233                                       "ProductName\tMSITEST\n"
1234                                       "ProductVersion\t1.1.1\n"
1235                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n";
1236
1237 static const CHAR vp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1238                                            "s72\ti2\tS64\tS0\tS255\n"
1239                                            "CustomAction\tAction\n"
1240                                            "SetProductID1\t51\tProductID\t1\t\n"
1241                                            "SetProductID2\t51\tProductID\t2\t\n"
1242                                            "TestProductID1\t19\t\t\tHalts installation\n"
1243                                            "TestProductID2\t19\t\t\tHalts installation\n";
1244
1245 static const CHAR vp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1246                                               "s72\tS255\tI2\n"
1247                                               "InstallExecuteSequence\tAction\n"
1248                                               "LaunchConditions\t\t100\n"
1249                                               "CostInitialize\t\t800\n"
1250                                               "FileCost\t\t900\n"
1251                                               "CostFinalize\t\t1000\n"
1252                                               "InstallValidate\t\t1400\n"
1253                                               "InstallInitialize\t\t1500\n"
1254                                               "SetProductID1\tSET_PRODUCT_ID=1\t3000\n"
1255                                               "SetProductID2\tSET_PRODUCT_ID=2\t3100\n"
1256                                               "ValidateProductID\t\t3200\n"
1257                                               "InstallExecute\t\t3300\n"
1258                                               "TestProductID1\tProductID=1\t3400\n"
1259                                               "TestProductID2\tProductID=\"123-1234567\"\t3500\n"
1260                                               "InstallFiles\t\t4000\n"
1261                                               "InstallFinalize\t\t6000\n";
1262
1263 static const CHAR odbc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1264                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1265                                     "File\tFile\n"
1266                                     "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n"
1267                                     "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n"
1268                                     "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n"
1269                                     "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n"
1270                                     "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n";
1271
1272 static const CHAR odbc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1273                                        "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1274                                        "Feature\tFeature\n"
1275                                        "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n";
1276
1277 static const CHAR odbc_feature_comp_dat[] = "Feature_\tComponent_\n"
1278                                             "s38\ts72\n"
1279                                             "FeatureComponents\tFeature_\tComponent_\n"
1280                                             "odbc\todbc\n";
1281
1282 static const CHAR odbc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1283                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
1284                                          "Component\tComponent\n"
1285                                          "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n";
1286
1287 static const CHAR odbc_driver_dat[] = "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n"
1288                                       "s72\ts72\ts255\ts72\tS72\n"
1289                                       "ODBCDriver\tDriver\n"
1290                                       "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n"
1291                                       "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n";
1292
1293 static const CHAR odbc_translator_dat[] = "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n"
1294                                           "s72\ts72\ts255\ts72\tS72\n"
1295                                           "ODBCTranslator\tTranslator\n"
1296                                           "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n"
1297                                           "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n";
1298
1299 static const CHAR odbc_datasource_dat[] = "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n"
1300                                           "s72\ts72\ts255\ts255\ti2\n"
1301                                           "ODBCDataSource\tDataSource\n"
1302                                           "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n";
1303
1304 static const CHAR odbc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1305                                                 "s72\tS255\tI2\n"
1306                                                 "InstallExecuteSequence\tAction\n"
1307                                                 "LaunchConditions\t\t100\n"
1308                                                 "CostInitialize\t\t800\n"
1309                                                 "FileCost\t\t900\n"
1310                                                 "CostFinalize\t\t1000\n"
1311                                                 "InstallValidate\t\t1400\n"
1312                                                 "InstallInitialize\t\t1500\n"
1313                                                 "InstallODBC\t\t3000\n"
1314                                                 "RemoveODBC\t\t3100\n"
1315                                                 "InstallFiles\t\t4000\n"
1316                                                 "InstallFinalize\t\t6000\n";
1317
1318 static const CHAR odbc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
1319                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
1320                                      "Media\tDiskId\n"
1321                                      "1\t5\t\t\tDISK1\t\n";
1322
1323 static const CHAR tl_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1324                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1325                                   "File\tFile\n"
1326                                   "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
1327
1328 static const CHAR tl_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1329                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1330                                      "Feature\tFeature\n"
1331                                      "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
1332
1333 static const CHAR tl_feature_comp_dat[] = "Feature_\tComponent_\n"
1334                                           "s38\ts72\n"
1335                                           "FeatureComponents\tFeature_\tComponent_\n"
1336                                           "typelib\ttypelib\n";
1337
1338 static const CHAR tl_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1339                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1340                                        "Component\tComponent\n"
1341                                        "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
1342
1343 static const CHAR tl_typelib_dat[] = "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
1344                                      "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
1345                                      "TypeLib\tLibID\tLanguage\tComponent_\n"
1346                                      "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
1347
1348 static const CHAR tl_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1349                                               "s72\tS255\tI2\n"
1350                                               "InstallExecuteSequence\tAction\n"
1351                                               "LaunchConditions\t\t100\n"
1352                                               "CostInitialize\t\t800\n"
1353                                               "FileCost\t\t900\n"
1354                                               "CostFinalize\t\t1000\n"
1355                                               "InstallValidate\t\t1400\n"
1356                                               "InstallInitialize\t\t1500\n"
1357                                               "ProcessComponents\t\t1600\n"
1358                                               "RemoveFiles\t\t1700\n"
1359                                               "InstallFiles\t\t2000\n"
1360                                               "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
1361                                               "UnregisterTypeLibraries\t\t3100\n"
1362                                               "RegisterProduct\t\t5100\n"
1363                                               "PublishFeatures\t\t5200\n"
1364                                               "PublishProduct\t\t5300\n"
1365                                               "InstallFinalize\t\t6000\n";
1366
1367 static const CHAR crs_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1368                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1369                                    "File\tFile\n"
1370                                    "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n";
1371
1372 static const CHAR crs_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1373                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1374                                       "Feature\tFeature\n"
1375                                       "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n";
1376
1377 static const CHAR crs_feature_comp_dat[] = "Feature_\tComponent_\n"
1378                                            "s38\ts72\n"
1379                                            "FeatureComponents\tFeature_\tComponent_\n"
1380                                            "shortcut\tshortcut\n";
1381
1382 static const CHAR crs_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1383                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1384                                         "Component\tComponent\n"
1385                                         "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n";
1386
1387 static const CHAR crs_shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
1388                                        "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n"
1389                                        "Shortcut\tShortcut\n"
1390                                        "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n";
1391
1392 static const CHAR crs_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1393                                                "s72\tS255\tI2\n"
1394                                                "InstallExecuteSequence\tAction\n"
1395                                                "LaunchConditions\t\t100\n"
1396                                                "CostInitialize\t\t800\n"
1397                                                "FileCost\t\t900\n"
1398                                                "CostFinalize\t\t1000\n"
1399                                                "InstallValidate\t\t1400\n"
1400                                                "InstallInitialize\t\t1500\n"
1401                                                "ProcessComponents\t\t1600\n"
1402                                                "RemoveFiles\t\t1700\n"
1403                                                "InstallFiles\t\t2000\n"
1404                                                "RemoveShortcuts\t\t3000\n"
1405                                                "CreateShortcuts\t\t3100\n"
1406                                                "RegisterProduct\t\t5000\n"
1407                                                "PublishFeatures\t\t5100\n"
1408                                                "PublishProduct\t\t5200\n"
1409                                                "InstallFinalize\t\t6000\n";
1410
1411 static const CHAR pub_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1412                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1413                                    "File\tFile\n"
1414                                    "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n";
1415
1416 static const CHAR pub_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1417                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1418                                       "Feature\tFeature\n"
1419                                       "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n";
1420
1421 static const CHAR pub_feature_comp_dat[] = "Feature_\tComponent_\n"
1422                                            "s38\ts72\n"
1423                                            "FeatureComponents\tFeature_\tComponent_\n"
1424                                            "publish\tpublish\n";
1425
1426 static const CHAR pub_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1427                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1428                                         "Component\tComponent\n"
1429                                         "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n";
1430
1431 static const CHAR pub_publish_component_dat[] = "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n"
1432                                                 "s38\ts255\ts72\tL255\ts38\n"
1433                                                 "PublishComponent\tComponentId\tQualifier\tComponent_\n"
1434                                                 "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n";
1435
1436 static const CHAR pub_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1437                                                "s72\tS255\tI2\n"
1438                                                "InstallExecuteSequence\tAction\n"
1439                                                "LaunchConditions\t\t100\n"
1440                                                "CostInitialize\t\t800\n"
1441                                                "FileCost\t\t900\n"
1442                                                "CostFinalize\t\t1000\n"
1443                                                "InstallValidate\t\t1400\n"
1444                                                "InstallInitialize\t\t1500\n"
1445                                                "ProcessComponents\t\t1600\n"
1446                                                "RemoveFiles\t\t1700\n"
1447                                                "InstallFiles\t\t2000\n"
1448                                                "PublishComponents\t\t3000\n"
1449                                                "UnpublishComponents\t\t3100\n"
1450                                                "RegisterProduct\t\t5000\n"
1451                                                "PublishFeatures\t\t5100\n"
1452                                                "PublishProduct\t\t5200\n"
1453                                                "InstallFinalize\t\t6000\n";
1454
1455 static const CHAR rd_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1456                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1457                                   "File\tFile\n"
1458                                   "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n"
1459                                   "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n"
1460                                   "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n";
1461
1462 static const CHAR rd_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1463                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1464                                      "Feature\tFeature\n"
1465                                      "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n";
1466
1467 static const CHAR rd_feature_comp_dat[] = "Feature_\tComponent_\n"
1468                                           "s38\ts72\n"
1469                                           "FeatureComponents\tFeature_\tComponent_\n"
1470                                           "duplicate\tduplicate\n";
1471
1472 static const CHAR rd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1473                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1474                                        "Component\tComponent\n"
1475                                        "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n"
1476                                        "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n";
1477
1478 static const CHAR rd_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
1479                                             "s72\ts72\ts72\tS255\tS72\n"
1480                                             "DuplicateFile\tFileKey\n"
1481                                             "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n"
1482                                             "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n"
1483                                             "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n";
1484
1485 static const CHAR rd_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1486                                               "s72\tS255\tI2\n"
1487                                               "InstallExecuteSequence\tAction\n"
1488                                               "LaunchConditions\t\t100\n"
1489                                               "CostInitialize\t\t800\n"
1490                                               "FileCost\t\t900\n"
1491                                               "CostFinalize\t\t1000\n"
1492                                               "InstallValidate\t\t1400\n"
1493                                               "InstallInitialize\t\t1500\n"
1494                                               "ProcessComponents\t\t1600\n"
1495                                               "RemoveDuplicateFiles\t\t1900\n"
1496                                               "InstallFiles\t\t2000\n"
1497                                               "DuplicateFiles\t\t2100\n"
1498                                               "RegisterProduct\t\t5000\n"
1499                                               "PublishFeatures\t\t5100\n"
1500                                               "PublishProduct\t\t5200\n"
1501                                               "InstallFinalize\t\t6000\n";
1502
1503 static const CHAR rrv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1504                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1505                                    "File\tFile\n"
1506                                    "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n";
1507
1508 static const CHAR rrv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1509                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1510                                       "Feature\tFeature\n"
1511                                       "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n";
1512
1513 static const CHAR rrv_feature_comp_dat[] = "Feature_\tComponent_\n"
1514                                            "s38\ts72\n"
1515                                            "FeatureComponents\tFeature_\tComponent_\n"
1516                                            "registry\tregistry\n";
1517
1518 static const CHAR rrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1519                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1520                                         "Component\tComponent\n"
1521                                         "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n";
1522
1523 static const CHAR rrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
1524                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
1525                                        "Registry\tRegistry\n"
1526                                        "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n"
1527                                        "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n"
1528                                        "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n";
1529
1530 static const CHAR rrv_remove_registry_dat[] = "RemoveRegistry\tRoot\tKey\tName\tComponent_\n"
1531                                               "s72\ti2\tl255\tL255\ts72\n"
1532                                               "RemoveRegistry\tRemoveRegistry\n"
1533                                               "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n"
1534                                               "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n"
1535                                               "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n";
1536
1537 static const CHAR rrv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1538                                                "s72\tS255\tI2\n"
1539                                                "InstallExecuteSequence\tAction\n"
1540                                                "LaunchConditions\t\t100\n"
1541                                                "CostInitialize\t\t800\n"
1542                                                "FileCost\t\t900\n"
1543                                                "CostFinalize\t\t1000\n"
1544                                                "InstallValidate\t\t1400\n"
1545                                                "InstallInitialize\t\t1500\n"
1546                                                "ProcessComponents\t\t1600\n"
1547                                                "RemoveFiles\t\t1700\n"
1548                                                "InstallFiles\t\t2000\n"
1549                                                "RemoveRegistryValues\t\t3000\n"
1550                                                "RegisterProduct\t\t5000\n"
1551                                                "PublishFeatures\t\t5100\n"
1552                                                "PublishProduct\t\t5200\n"
1553                                                "InstallFinalize\t\t6000\n";
1554
1555 static const CHAR frp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1556                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1557                                    "File\tFile\n"
1558                                    "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n";
1559
1560 static const CHAR frp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1561                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1562                                       "Feature\tFeature\n"
1563                                       "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n";
1564
1565 static const CHAR frp_feature_comp_dat[] = "Feature_\tComponent_\n"
1566                                            "s38\ts72\n"
1567                                            "FeatureComponents\tFeature_\tComponent_\n"
1568                                            "product\tproduct\n";
1569
1570 static const CHAR frp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1571                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1572                                         "Component\tComponent\n"
1573                                         "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n";
1574
1575 static const CHAR frp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1576                                             "s72\ti2\tS64\tS0\tS255\n"
1577                                             "CustomAction\tAction\n"
1578                                             "TestProp\t19\t\t\tPROP set\n";
1579
1580 static const CHAR frp_upgrade_dat[] = "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1581                                       "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1582                                       "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1583                                       "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n";
1584
1585 static const CHAR frp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1586                                                "s72\tS255\tI2\n"
1587                                                "InstallExecuteSequence\tAction\n"
1588                                                "FindRelatedProducts\t\t50\n"
1589                                                "TestProp\tPROP AND NOT REMOVE\t51\n"
1590                                                "LaunchConditions\t\t100\n"
1591                                                "CostInitialize\t\t800\n"
1592                                                "FileCost\t\t900\n"
1593                                                "CostFinalize\t\t1000\n"
1594                                                "InstallValidate\t\t1400\n"
1595                                                "InstallInitialize\t\t1500\n"
1596                                                "ProcessComponents\t\t1600\n"
1597                                                "RemoveFiles\t\t1700\n"
1598                                                "InstallFiles\t\t2000\n"
1599                                                "RegisterProduct\t\t5000\n"
1600                                                "PublishFeatures\t\t5100\n"
1601                                                "PublishProduct\t\t5200\n"
1602                                                "InstallFinalize\t\t6000\n";
1603
1604 static const CHAR riv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1605                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1606                                    "File\tFile\n"
1607                                    "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n";
1608
1609 static const CHAR riv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1610                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1611                                       "Feature\tFeature\n"
1612                                       "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n";
1613
1614 static const CHAR riv_feature_comp_dat[] = "Feature_\tComponent_\n"
1615                                            "s38\ts72\n"
1616                                            "FeatureComponents\tFeature_\tComponent_\n"
1617                                            "inifile\tinifile\n";
1618
1619 static const CHAR riv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1620                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1621                                         "Component\tComponent\n"
1622                                         "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n";
1623
1624 static const CHAR riv_ini_file_dat[] = "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1625                                        "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n"
1626                                        "IniFile\tIniFile\n"
1627                                        "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n";
1628
1629 static const CHAR riv_remove_ini_file_dat[] = "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1630                                               "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n"
1631                                               "RemoveIniFile\tRemoveIniFile\n"
1632                                               "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n";
1633
1634 static const CHAR riv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1635                                                "s72\tS255\tI2\n"
1636                                                "InstallExecuteSequence\tAction\n"
1637                                                "LaunchConditions\t\t100\n"
1638                                                "CostInitialize\t\t800\n"
1639                                                "FileCost\t\t900\n"
1640                                                "CostFinalize\t\t1000\n"
1641                                                "InstallValidate\t\t1400\n"
1642                                                "InstallInitialize\t\t1500\n"
1643                                                "ProcessComponents\t\t1600\n"
1644                                                "RemoveFiles\t\t1700\n"
1645                                                "InstallFiles\t\t2000\n"
1646                                                "RemoveIniValues\t\t3000\n"
1647                                                "RegisterProduct\t\t5000\n"
1648                                                "PublishFeatures\t\t5100\n"
1649                                                "PublishProduct\t\t5200\n"
1650                                                "InstallFinalize\t\t6000\n";
1651
1652 static const CHAR res_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1653                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1654                                    "File\tFile\n"
1655                                    "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n";
1656
1657 static const CHAR res_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1658                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1659                                       "Feature\tFeature\n"
1660                                       "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n";
1661
1662 static const CHAR res_feature_comp_dat[] = "Feature_\tComponent_\n"
1663                                            "s38\ts72\n"
1664                                            "FeatureComponents\tFeature_\tComponent_\n"
1665                                            "envvar\tenvvar\n";
1666
1667 static const CHAR res_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1668                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1669                                         "Component\tComponent\n"
1670                                         "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n";
1671
1672 static const CHAR res_environment_dat[] = "Environment\tName\tValue\tComponent_\n"
1673                                           "s72\tl255\tL255\ts72\n"
1674                                           "Environment\tEnvironment\n"
1675                                           "var1\t=-MSITESTVAR1\t1\tenvvar\n"
1676                                           "var2\t=+-MSITESTVAR2\t1\tenvvar\n"
1677                                           "var3\t=MSITESTVAR3\t1\tenvvar\n"
1678                                           "var4\t=-MSITESTVAR4\t\tenvvar\n"
1679                                           "var5\t=MSITESTVAR5\t\tenvvar\n";
1680
1681 static const CHAR res_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1682                                                "s72\tS255\tI2\n"
1683                                                "InstallExecuteSequence\tAction\n"
1684                                                "LaunchConditions\t\t100\n"
1685                                                "CostInitialize\t\t800\n"
1686                                                "FileCost\t\t900\n"
1687                                                "CostFinalize\t\t1000\n"
1688                                                "InstallValidate\t\t1400\n"
1689                                                "InstallInitialize\t\t1500\n"
1690                                                "ProcessComponents\t\t1600\n"
1691                                                "RemoveFiles\t\t1700\n"
1692                                                "InstallFiles\t\t2000\n"
1693                                                "RemoveEnvironmentStrings\t\t3000\n"
1694                                                "RegisterProduct\t\t5000\n"
1695                                                "PublishFeatures\t\t5100\n"
1696                                                "PublishProduct\t\t5200\n"
1697                                                "InstallFinalize\t\t6000\n";
1698
1699 static const CHAR rci_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1700                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1701                                    "File\tFile\n"
1702                                    "class.txt\tclass\tclass.txt\t1000\t\t\t8192\t1\n";
1703
1704 static const CHAR rci_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1705                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1706                                       "Feature\tFeature\n"
1707                                       "class\t\t\tclass feature\t1\t2\tMSITESTDIR\t0\n";
1708
1709 static const CHAR rci_feature_comp_dat[] = "Feature_\tComponent_\n"
1710                                            "s38\ts72\n"
1711                                            "FeatureComponents\tFeature_\tComponent_\n"
1712                                            "class\tclass\n";
1713
1714 static const CHAR rci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1715                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1716                                         "Component\tComponent\n"
1717                                         "class\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tclass.txt\n";
1718
1719 static const CHAR rci_appid_dat[] = "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n"
1720                                     "s38\tS255\tS255\tS255\tS255\tI2\tI2\n"
1721                                     "AppId\tAppId\n"
1722                                     "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n";
1723
1724 static const CHAR rci_class_dat[] = "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n"
1725                                     "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n"
1726                                     "Class\tCLSID\tContext\tComponent_\n"
1727                                     "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tclass\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tclass\t\n";
1728
1729 static const CHAR rci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1730                                                "s72\tS255\tI2\n"
1731                                                "InstallExecuteSequence\tAction\n"
1732                                                "LaunchConditions\t\t100\n"
1733                                                "CostInitialize\t\t800\n"
1734                                                "FileCost\t\t900\n"
1735                                                "CostFinalize\t\t1000\n"
1736                                                "InstallValidate\t\t1400\n"
1737                                                "InstallInitialize\t\t1500\n"
1738                                                "ProcessComponents\t\t1600\n"
1739                                                "RemoveFiles\t\t1700\n"
1740                                                "InstallFiles\t\t2000\n"
1741                                                "UnregisterClassInfo\t\t3000\n"
1742                                                "RegisterClassInfo\t\t4000\n"
1743                                                "RegisterProduct\t\t5000\n"
1744                                                "PublishFeatures\t\t5100\n"
1745                                                "PublishProduct\t\t5200\n"
1746                                                "InstallFinalize\t\t6000\n";
1747
1748 static const CHAR rei_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1749                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1750                                    "File\tFile\n"
1751                                    "extension.txt\textension\textension.txt\t1000\t\t\t8192\t1\n";
1752
1753 static const CHAR rei_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1754                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1755                                       "Feature\tFeature\n"
1756                                       "extension\t\t\textension feature\t1\t2\tMSITESTDIR\t0\n";
1757
1758 static const CHAR rei_feature_comp_dat[] = "Feature_\tComponent_\n"
1759                                            "s38\ts72\n"
1760                                            "FeatureComponents\tFeature_\tComponent_\n"
1761                                            "extension\textension\n";
1762
1763 static const CHAR rei_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1764                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1765                                         "Component\tComponent\n"
1766                                         "extension\t{9A3060D4-60BA-4A82-AB55-9FB148AD013C}\tMSITESTDIR\t0\t\textension.txt\n";
1767
1768 static const CHAR rei_extension_dat[] = "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1769                                         "s255\ts72\tS255\tS64\ts38\n"
1770                                         "Extension\tExtension\tComponent_\n"
1771                                         "extension\textension\tProg.Id.1\t\textension\n";
1772
1773 static const CHAR rei_verb_dat[] = "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1774                                    "s255\ts32\tI2\tL255\tL255\n"
1775                                    "Verb\tExtension_\tVerb\n"
1776                                    "extension\tOpen\t1\t&Open\t/argument\n";
1777
1778 static const CHAR rei_progid_dat[] = "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n"
1779                                      "s255\tS255\tS38\tL255\tS72\tI2\n"
1780                                      "ProgId\tProgId\n"
1781                                      "Prog.Id.1\t\t\tdescription\t\t\n";
1782
1783 static const CHAR rei_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1784                                                "s72\tS255\tI2\n"
1785                                                "InstallExecuteSequence\tAction\n"
1786                                                "LaunchConditions\t\t100\n"
1787                                                "CostInitialize\t\t800\n"
1788                                                "FileCost\t\t900\n"
1789                                                "CostFinalize\t\t1000\n"
1790                                                "InstallValidate\t\t1400\n"
1791                                                "InstallInitialize\t\t1500\n"
1792                                                "ProcessComponents\t\t1600\n"
1793                                                "RemoveFiles\t\t1700\n"
1794                                                "InstallFiles\t\t2000\n"
1795                                                "UnregisterExtensionInfo\t\t3000\n"
1796                                                "RegisterExtensionInfo\t\t4000\n"
1797                                                "RegisterProduct\t\t5000\n"
1798                                                "PublishFeatures\t\t5100\n"
1799                                                "PublishProduct\t\t5200\n"
1800                                                "InstallFinalize\t\t6000\n";
1801
1802 typedef struct _msi_table
1803 {
1804     const CHAR *filename;
1805     const CHAR *data;
1806     int size;
1807 } msi_table;
1808
1809 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
1810
1811 static const msi_table tables[] =
1812 {
1813     ADD_TABLE(component),
1814     ADD_TABLE(directory),
1815     ADD_TABLE(feature),
1816     ADD_TABLE(feature_comp),
1817     ADD_TABLE(file),
1818     ADD_TABLE(install_exec_seq),
1819     ADD_TABLE(media),
1820     ADD_TABLE(property),
1821     ADD_TABLE(registry),
1822     ADD_TABLE(service_install),
1823     ADD_TABLE(service_control)
1824 };
1825
1826 static const msi_table sc_tables[] =
1827 {
1828     ADD_TABLE(component),
1829     ADD_TABLE(directory),
1830     ADD_TABLE(feature),
1831     ADD_TABLE(feature_comp),
1832     ADD_TABLE(file),
1833     ADD_TABLE(install_exec_seq),
1834     ADD_TABLE(media),
1835     ADD_TABLE(property),
1836     ADD_TABLE(shortcut)
1837 };
1838
1839 static const msi_table ps_tables[] =
1840 {
1841     ADD_TABLE(component),
1842     ADD_TABLE(directory),
1843     ADD_TABLE(feature),
1844     ADD_TABLE(feature_comp),
1845     ADD_TABLE(file),
1846     ADD_TABLE(install_exec_seq),
1847     ADD_TABLE(media),
1848     ADD_TABLE(property),
1849     ADD_TABLE(condition)
1850 };
1851
1852 static const msi_table env_tables[] =
1853 {
1854     ADD_TABLE(component),
1855     ADD_TABLE(directory),
1856     ADD_TABLE(feature),
1857     ADD_TABLE(feature_comp),
1858     ADD_TABLE(file),
1859     ADD_TABLE(install_exec_seq),
1860     ADD_TABLE(media),
1861     ADD_TABLE(property),
1862     ADD_TABLE(environment)
1863 };
1864
1865 static const msi_table up_tables[] =
1866 {
1867     ADD_TABLE(component),
1868     ADD_TABLE(directory),
1869     ADD_TABLE(feature),
1870     ADD_TABLE(feature_comp),
1871     ADD_TABLE(file),
1872     ADD_TABLE(install_exec_seq),
1873     ADD_TABLE(media),
1874     ADD_TABLE(up_property),
1875     ADD_TABLE(registry),
1876     ADD_TABLE(service_install),
1877     ADD_TABLE(service_control)
1878 };
1879
1880 static const msi_table up2_tables[] =
1881 {
1882     ADD_TABLE(component),
1883     ADD_TABLE(directory),
1884     ADD_TABLE(feature),
1885     ADD_TABLE(feature_comp),
1886     ADD_TABLE(file),
1887     ADD_TABLE(install_exec_seq),
1888     ADD_TABLE(media),
1889     ADD_TABLE(up2_property),
1890     ADD_TABLE(registry),
1891     ADD_TABLE(service_install),
1892     ADD_TABLE(service_control)
1893 };
1894
1895 static const msi_table up3_tables[] =
1896 {
1897     ADD_TABLE(component),
1898     ADD_TABLE(directory),
1899     ADD_TABLE(feature),
1900     ADD_TABLE(feature_comp),
1901     ADD_TABLE(file),
1902     ADD_TABLE(install_exec_seq),
1903     ADD_TABLE(media),
1904     ADD_TABLE(up3_property),
1905     ADD_TABLE(registry),
1906     ADD_TABLE(service_install),
1907     ADD_TABLE(service_control)
1908 };
1909
1910 static const msi_table up4_tables[] =
1911 {
1912     ADD_TABLE(component),
1913     ADD_TABLE(directory),
1914     ADD_TABLE(feature),
1915     ADD_TABLE(feature_comp),
1916     ADD_TABLE(file),
1917     ADD_TABLE(pp_install_exec_seq),
1918     ADD_TABLE(media),
1919     ADD_TABLE(property),
1920     ADD_TABLE(registry),
1921     ADD_TABLE(service_install),
1922     ADD_TABLE(service_control)
1923 };
1924
1925 static const msi_table up5_tables[] =
1926 {
1927     ADD_TABLE(component),
1928     ADD_TABLE(directory),
1929     ADD_TABLE(feature),
1930     ADD_TABLE(feature_comp),
1931     ADD_TABLE(file),
1932     ADD_TABLE(pp_install_exec_seq),
1933     ADD_TABLE(media),
1934     ADD_TABLE(up_property),
1935     ADD_TABLE(registry),
1936     ADD_TABLE(service_install),
1937     ADD_TABLE(service_control)
1938 };
1939
1940 static const msi_table up6_tables[] =
1941 {
1942     ADD_TABLE(component),
1943     ADD_TABLE(directory),
1944     ADD_TABLE(feature),
1945     ADD_TABLE(feature_comp),
1946     ADD_TABLE(file),
1947     ADD_TABLE(pp_install_exec_seq),
1948     ADD_TABLE(media),
1949     ADD_TABLE(up2_property),
1950     ADD_TABLE(registry),
1951     ADD_TABLE(service_install),
1952     ADD_TABLE(service_control)
1953 };
1954
1955 static const msi_table up7_tables[] =
1956 {
1957     ADD_TABLE(component),
1958     ADD_TABLE(directory),
1959     ADD_TABLE(feature),
1960     ADD_TABLE(feature_comp),
1961     ADD_TABLE(file),
1962     ADD_TABLE(pp_install_exec_seq),
1963     ADD_TABLE(media),
1964     ADD_TABLE(up3_property),
1965     ADD_TABLE(registry),
1966     ADD_TABLE(service_install),
1967     ADD_TABLE(service_control)
1968 };
1969
1970 static const msi_table cc_tables[] =
1971 {
1972     ADD_TABLE(cc_component),
1973     ADD_TABLE(directory),
1974     ADD_TABLE(cc_feature),
1975     ADD_TABLE(cc_feature_comp),
1976     ADD_TABLE(cc_file),
1977     ADD_TABLE(install_exec_seq),
1978     ADD_TABLE(cc_media),
1979     ADD_TABLE(property),
1980 };
1981
1982 static const msi_table cc2_tables[] =
1983 {
1984     ADD_TABLE(cc2_component),
1985     ADD_TABLE(directory),
1986     ADD_TABLE(cc_feature),
1987     ADD_TABLE(cc_feature_comp),
1988     ADD_TABLE(cc2_file),
1989     ADD_TABLE(install_exec_seq),
1990     ADD_TABLE(cc_media),
1991     ADD_TABLE(property),
1992 };
1993
1994 static const msi_table co_tables[] =
1995 {
1996     ADD_TABLE(cc_component),
1997     ADD_TABLE(directory),
1998     ADD_TABLE(cc_feature),
1999     ADD_TABLE(cc_feature_comp),
2000     ADD_TABLE(co_file),
2001     ADD_TABLE(install_exec_seq),
2002     ADD_TABLE(co_media),
2003     ADD_TABLE(property),
2004 };
2005
2006 static const msi_table co2_tables[] =
2007 {
2008     ADD_TABLE(cc_component),
2009     ADD_TABLE(directory),
2010     ADD_TABLE(cc_feature),
2011     ADD_TABLE(cc_feature_comp),
2012     ADD_TABLE(cc_file),
2013     ADD_TABLE(install_exec_seq),
2014     ADD_TABLE(co2_media),
2015     ADD_TABLE(property),
2016 };
2017
2018 static const msi_table mm_tables[] =
2019 {
2020     ADD_TABLE(cc_component),
2021     ADD_TABLE(directory),
2022     ADD_TABLE(cc_feature),
2023     ADD_TABLE(cc_feature_comp),
2024     ADD_TABLE(mm_file),
2025     ADD_TABLE(install_exec_seq),
2026     ADD_TABLE(mm_media),
2027     ADD_TABLE(property),
2028 };
2029
2030 static const msi_table ss_tables[] =
2031 {
2032     ADD_TABLE(cc_component),
2033     ADD_TABLE(directory),
2034     ADD_TABLE(cc_feature),
2035     ADD_TABLE(cc_feature_comp),
2036     ADD_TABLE(cc_file),
2037     ADD_TABLE(install_exec_seq),
2038     ADD_TABLE(ss_media),
2039     ADD_TABLE(property),
2040 };
2041
2042 static const msi_table ui_tables[] =
2043 {
2044     ADD_TABLE(ui_component),
2045     ADD_TABLE(directory),
2046     ADD_TABLE(cc_feature),
2047     ADD_TABLE(cc_feature_comp),
2048     ADD_TABLE(cc_file),
2049     ADD_TABLE(install_exec_seq),
2050     ADD_TABLE(ui_install_ui_seq),
2051     ADD_TABLE(ui_custom_action),
2052     ADD_TABLE(cc_media),
2053     ADD_TABLE(property),
2054 };
2055
2056 static const msi_table rof_tables[] =
2057 {
2058     ADD_TABLE(rof_component),
2059     ADD_TABLE(directory),
2060     ADD_TABLE(rof_feature),
2061     ADD_TABLE(rof_feature_comp),
2062     ADD_TABLE(rof_file),
2063     ADD_TABLE(install_exec_seq),
2064     ADD_TABLE(rof_media),
2065     ADD_TABLE(property),
2066 };
2067
2068 static const msi_table rofc_tables[] =
2069 {
2070     ADD_TABLE(rof_component),
2071     ADD_TABLE(directory),
2072     ADD_TABLE(rof_feature),
2073     ADD_TABLE(rof_feature_comp),
2074     ADD_TABLE(rofc_file),
2075     ADD_TABLE(install_exec_seq),
2076     ADD_TABLE(rofc_media),
2077     ADD_TABLE(property),
2078 };
2079
2080 static const msi_table sdp_tables[] =
2081 {
2082     ADD_TABLE(rof_component),
2083     ADD_TABLE(directory),
2084     ADD_TABLE(rof_feature),
2085     ADD_TABLE(rof_feature_comp),
2086     ADD_TABLE(rof_file),
2087     ADD_TABLE(sdp_install_exec_seq),
2088     ADD_TABLE(sdp_custom_action),
2089     ADD_TABLE(rof_media),
2090     ADD_TABLE(property),
2091 };
2092
2093 static const msi_table cie_tables[] =
2094 {
2095     ADD_TABLE(cie_component),
2096     ADD_TABLE(directory),
2097     ADD_TABLE(cc_feature),
2098     ADD_TABLE(cie_feature_comp),
2099     ADD_TABLE(cie_file),
2100     ADD_TABLE(install_exec_seq),
2101     ADD_TABLE(cie_media),
2102     ADD_TABLE(property),
2103 };
2104
2105 static const msi_table ci_tables[] =
2106 {
2107     ADD_TABLE(ci_component),
2108     ADD_TABLE(directory),
2109     ADD_TABLE(rof_feature),
2110     ADD_TABLE(rof_feature_comp),
2111     ADD_TABLE(rof_file),
2112     ADD_TABLE(ci_install_exec_seq),
2113     ADD_TABLE(rof_media),
2114     ADD_TABLE(property),
2115     ADD_TABLE(ci_custom_action),
2116 };
2117
2118 static const msi_table ci2_tables[] =
2119 {
2120     ADD_TABLE(ci2_component),
2121     ADD_TABLE(directory),
2122     ADD_TABLE(rof_feature),
2123     ADD_TABLE(ci2_feature_comp),
2124     ADD_TABLE(ci2_file),
2125     ADD_TABLE(install_exec_seq),
2126     ADD_TABLE(rof_media),
2127     ADD_TABLE(property),
2128 };
2129
2130 static const msi_table spf_tables[] =
2131 {
2132     ADD_TABLE(ci_component),
2133     ADD_TABLE(directory),
2134     ADD_TABLE(rof_feature),
2135     ADD_TABLE(rof_feature_comp),
2136     ADD_TABLE(rof_file),
2137     ADD_TABLE(spf_install_exec_seq),
2138     ADD_TABLE(rof_media),
2139     ADD_TABLE(property),
2140     ADD_TABLE(spf_custom_action),
2141     ADD_TABLE(spf_install_ui_seq),
2142 };
2143
2144 static const msi_table pp_tables[] =
2145 {
2146     ADD_TABLE(ci_component),
2147     ADD_TABLE(directory),
2148     ADD_TABLE(rof_feature),
2149     ADD_TABLE(rof_feature_comp),
2150     ADD_TABLE(rof_file),
2151     ADD_TABLE(pp_install_exec_seq),
2152     ADD_TABLE(rof_media),
2153     ADD_TABLE(property),
2154 };
2155
2156 static const msi_table ppc_tables[] =
2157 {
2158     ADD_TABLE(ppc_component),
2159     ADD_TABLE(directory),
2160     ADD_TABLE(rof_feature),
2161     ADD_TABLE(ppc_feature_comp),
2162     ADD_TABLE(ppc_file),
2163     ADD_TABLE(pp_install_exec_seq),
2164     ADD_TABLE(ppc_media),
2165     ADD_TABLE(property),
2166 };
2167
2168 static const msi_table lus0_tables[] =
2169 {
2170     ADD_TABLE(ci_component),
2171     ADD_TABLE(directory),
2172     ADD_TABLE(rof_feature),
2173     ADD_TABLE(rof_feature_comp),
2174     ADD_TABLE(rof_file),
2175     ADD_TABLE(pp_install_exec_seq),
2176     ADD_TABLE(rof_media),
2177     ADD_TABLE(property),
2178 };
2179
2180 static const msi_table lus1_tables[] =
2181 {
2182     ADD_TABLE(ci_component),
2183     ADD_TABLE(directory),
2184     ADD_TABLE(rof_feature),
2185     ADD_TABLE(rof_feature_comp),
2186     ADD_TABLE(rof_file),
2187     ADD_TABLE(pp_install_exec_seq),
2188     ADD_TABLE(rofc_media),
2189     ADD_TABLE(property),
2190 };
2191
2192 static const msi_table lus2_tables[] =
2193 {
2194     ADD_TABLE(ci_component),
2195     ADD_TABLE(directory),
2196     ADD_TABLE(rof_feature),
2197     ADD_TABLE(rof_feature_comp),
2198     ADD_TABLE(rof_file),
2199     ADD_TABLE(pp_install_exec_seq),
2200     ADD_TABLE(lus2_media),
2201     ADD_TABLE(property),
2202 };
2203
2204 static const msi_table tp_tables[] =
2205 {
2206     ADD_TABLE(tp_component),
2207     ADD_TABLE(directory),
2208     ADD_TABLE(rof_feature),
2209     ADD_TABLE(ci2_feature_comp),
2210     ADD_TABLE(ci2_file),
2211     ADD_TABLE(install_exec_seq),
2212     ADD_TABLE(rof_media),
2213     ADD_TABLE(property),
2214 };
2215
2216 static const msi_table cwd_tables[] =
2217 {
2218     ADD_TABLE(cwd_component),
2219     ADD_TABLE(directory),
2220     ADD_TABLE(rof_feature),
2221     ADD_TABLE(ci2_feature_comp),
2222     ADD_TABLE(ci2_file),
2223     ADD_TABLE(install_exec_seq),
2224     ADD_TABLE(rof_media),
2225     ADD_TABLE(property),
2226 };
2227
2228 static const msi_table adm_tables[] =
2229 {
2230     ADD_TABLE(adm_component),
2231     ADD_TABLE(directory),
2232     ADD_TABLE(rof_feature),
2233     ADD_TABLE(ci2_feature_comp),
2234     ADD_TABLE(ci2_file),
2235     ADD_TABLE(install_exec_seq),
2236     ADD_TABLE(rof_media),
2237     ADD_TABLE(property),
2238     ADD_TABLE(adm_custom_action),
2239     ADD_TABLE(adm_admin_exec_seq),
2240 };
2241
2242 static const msi_table amp_tables[] =
2243 {
2244     ADD_TABLE(amp_component),
2245     ADD_TABLE(directory),
2246     ADD_TABLE(rof_feature),
2247     ADD_TABLE(ci2_feature_comp),
2248     ADD_TABLE(ci2_file),
2249     ADD_TABLE(install_exec_seq),
2250     ADD_TABLE(rof_media),
2251     ADD_TABLE(property),
2252 };
2253
2254 static const msi_table rem_tables[] =
2255 {
2256     ADD_TABLE(rem_component),
2257     ADD_TABLE(directory),
2258     ADD_TABLE(rof_feature),
2259     ADD_TABLE(rem_feature_comp),
2260     ADD_TABLE(rem_file),
2261     ADD_TABLE(rem_install_exec_seq),
2262     ADD_TABLE(rof_media),
2263     ADD_TABLE(property),
2264     ADD_TABLE(rem_remove_files),
2265 };
2266
2267 static const msi_table mov_tables[] =
2268 {
2269     ADD_TABLE(cwd_component),
2270     ADD_TABLE(directory),
2271     ADD_TABLE(rof_feature),
2272     ADD_TABLE(ci2_feature_comp),
2273     ADD_TABLE(ci2_file),
2274     ADD_TABLE(install_exec_seq),
2275     ADD_TABLE(rof_media),
2276     ADD_TABLE(property),
2277     ADD_TABLE(mov_move_file),
2278 };
2279
2280 static const msi_table mc_tables[] =
2281 {
2282     ADD_TABLE(mc_component),
2283     ADD_TABLE(directory),
2284     ADD_TABLE(cc_feature),
2285     ADD_TABLE(cie_feature_comp),
2286     ADD_TABLE(mc_file),
2287     ADD_TABLE(install_exec_seq),
2288     ADD_TABLE(mc_media),
2289     ADD_TABLE(property),
2290     ADD_TABLE(mc_file_hash),
2291 };
2292
2293 static const msi_table df_tables[] =
2294 {
2295     ADD_TABLE(rof_component),
2296     ADD_TABLE(df_directory),
2297     ADD_TABLE(rof_feature),
2298     ADD_TABLE(rof_feature_comp),
2299     ADD_TABLE(rof_file),
2300     ADD_TABLE(install_exec_seq),
2301     ADD_TABLE(rof_media),
2302     ADD_TABLE(property),
2303     ADD_TABLE(df_duplicate_file),
2304 };
2305
2306 static const msi_table wrv_tables[] =
2307 {
2308     ADD_TABLE(wrv_component),
2309     ADD_TABLE(directory),
2310     ADD_TABLE(rof_feature),
2311     ADD_TABLE(ci2_feature_comp),
2312     ADD_TABLE(ci2_file),
2313     ADD_TABLE(install_exec_seq),
2314     ADD_TABLE(rof_media),
2315     ADD_TABLE(property),
2316     ADD_TABLE(wrv_registry),
2317 };
2318
2319 static const msi_table sf_tables[] =
2320 {
2321     ADD_TABLE(wrv_component),
2322     ADD_TABLE(directory),
2323     ADD_TABLE(rof_feature),
2324     ADD_TABLE(ci2_feature_comp),
2325     ADD_TABLE(ci2_file),
2326     ADD_TABLE(install_exec_seq),
2327     ADD_TABLE(rof_media),
2328     ADD_TABLE(property),
2329 };
2330
2331 static const msi_table ca51_tables[] =
2332 {
2333     ADD_TABLE(ca51_component),
2334     ADD_TABLE(directory),
2335     ADD_TABLE(rof_feature),
2336     ADD_TABLE(ci2_feature_comp),
2337     ADD_TABLE(ci2_file),
2338     ADD_TABLE(ca51_install_exec_seq),
2339     ADD_TABLE(rof_media),
2340     ADD_TABLE(property),
2341     ADD_TABLE(ca51_custom_action),
2342 };
2343
2344 static const msi_table is_tables[] =
2345 {
2346     ADD_TABLE(is_component),
2347     ADD_TABLE(directory),
2348     ADD_TABLE(is_feature),
2349     ADD_TABLE(is_feature_comp),
2350     ADD_TABLE(is_file),
2351     ADD_TABLE(install_exec_seq),
2352     ADD_TABLE(is_media),
2353     ADD_TABLE(property),
2354 };
2355
2356 static const msi_table sp_tables[] =
2357 {
2358     ADD_TABLE(sp_component),
2359     ADD_TABLE(sp_directory),
2360     ADD_TABLE(rof_feature),
2361     ADD_TABLE(ci2_feature_comp),
2362     ADD_TABLE(ci2_file),
2363     ADD_TABLE(install_exec_seq),
2364     ADD_TABLE(rof_media),
2365     ADD_TABLE(property),
2366 };
2367
2368 static const msi_table mcp_tables[] =
2369 {
2370     ADD_TABLE(mcp_component),
2371     ADD_TABLE(directory),
2372     ADD_TABLE(mcp_feature),
2373     ADD_TABLE(mcp_feature_comp),
2374     ADD_TABLE(rem_file),
2375     ADD_TABLE(rem_install_exec_seq),
2376     ADD_TABLE(rof_media),
2377     ADD_TABLE(property),
2378 };
2379
2380 static const msi_table mcomp_tables[] =
2381 {
2382     ADD_TABLE(mcp_component),
2383     ADD_TABLE(directory),
2384     ADD_TABLE(mcp_feature),
2385     ADD_TABLE(mcp_feature_comp),
2386     ADD_TABLE(mcomp_file),
2387     ADD_TABLE(rem_install_exec_seq),
2388     ADD_TABLE(rof_media),
2389     ADD_TABLE(property),
2390 };
2391
2392 static const msi_table ai_tables[] =
2393 {
2394     ADD_TABLE(component),
2395     ADD_TABLE(directory),
2396     ADD_TABLE(feature),
2397     ADD_TABLE(feature_comp),
2398     ADD_TABLE(ai_file),
2399     ADD_TABLE(install_exec_seq),
2400     ADD_TABLE(media),
2401     ADD_TABLE(property)
2402 };
2403
2404 static const msi_table pc_tables[] =
2405 {
2406     ADD_TABLE(ca51_component),
2407     ADD_TABLE(directory),
2408     ADD_TABLE(rof_feature),
2409     ADD_TABLE(ci2_feature_comp),
2410     ADD_TABLE(ci2_file),
2411     ADD_TABLE(install_exec_seq),
2412     ADD_TABLE(rof_media),
2413     ADD_TABLE(property)
2414 };
2415
2416 static const msi_table ip_tables[] =
2417 {
2418     ADD_TABLE(component),
2419     ADD_TABLE(directory),
2420     ADD_TABLE(feature),
2421     ADD_TABLE(feature_comp),
2422     ADD_TABLE(file),
2423     ADD_TABLE(ip_install_exec_seq),
2424     ADD_TABLE(ip_custom_action),
2425     ADD_TABLE(media),
2426     ADD_TABLE(property)
2427 };
2428
2429 static const msi_table aup_tables[] =
2430 {
2431     ADD_TABLE(component),
2432     ADD_TABLE(directory),
2433     ADD_TABLE(feature),
2434     ADD_TABLE(feature_comp),
2435     ADD_TABLE(file),
2436     ADD_TABLE(aup_install_exec_seq),
2437     ADD_TABLE(aup_custom_action),
2438     ADD_TABLE(media),
2439     ADD_TABLE(property)
2440 };
2441
2442 static const msi_table aup2_tables[] =
2443 {
2444     ADD_TABLE(component),
2445     ADD_TABLE(directory),
2446     ADD_TABLE(feature),
2447     ADD_TABLE(feature_comp),
2448     ADD_TABLE(file),
2449     ADD_TABLE(aup2_install_exec_seq),
2450     ADD_TABLE(aup_custom_action),
2451     ADD_TABLE(media),
2452     ADD_TABLE(aup_property)
2453 };
2454
2455 static const msi_table aup3_tables[] =
2456 {
2457     ADD_TABLE(component),
2458     ADD_TABLE(directory),
2459     ADD_TABLE(feature),
2460     ADD_TABLE(feature_comp),
2461     ADD_TABLE(file),
2462     ADD_TABLE(aup2_install_exec_seq),
2463     ADD_TABLE(aup_custom_action),
2464     ADD_TABLE(media),
2465     ADD_TABLE(aup2_property)
2466 };
2467
2468 static const msi_table aup4_tables[] =
2469 {
2470     ADD_TABLE(component),
2471     ADD_TABLE(directory),
2472     ADD_TABLE(feature),
2473     ADD_TABLE(feature_comp),
2474     ADD_TABLE(file),
2475     ADD_TABLE(aup3_install_exec_seq),
2476     ADD_TABLE(aup_custom_action),
2477     ADD_TABLE(media),
2478     ADD_TABLE(aup2_property)
2479 };
2480
2481 static const msi_table fiu_tables[] =
2482 {
2483     ADD_TABLE(rof_component),
2484     ADD_TABLE(directory),
2485     ADD_TABLE(rof_feature),
2486     ADD_TABLE(rof_feature_comp),
2487     ADD_TABLE(rof_file),
2488     ADD_TABLE(pp_install_exec_seq),
2489     ADD_TABLE(rof_media),
2490     ADD_TABLE(property),
2491 };
2492
2493 static const msi_table fiuc_tables[] =
2494 {
2495     ADD_TABLE(rof_component),
2496     ADD_TABLE(directory),
2497     ADD_TABLE(rof_feature),
2498     ADD_TABLE(rof_feature_comp),
2499     ADD_TABLE(rofc_file),
2500     ADD_TABLE(pp_install_exec_seq),
2501     ADD_TABLE(rofc_media),
2502     ADD_TABLE(property),
2503 };
2504
2505 static const msi_table cf_tables[] =
2506 {
2507     ADD_TABLE(component),
2508     ADD_TABLE(directory),
2509     ADD_TABLE(feature),
2510     ADD_TABLE(feature_comp),
2511     ADD_TABLE(file),
2512     ADD_TABLE(cf_create_folders),
2513     ADD_TABLE(cf_install_exec_seq),
2514     ADD_TABLE(cf_custom_action),
2515     ADD_TABLE(media),
2516     ADD_TABLE(property)
2517 };
2518
2519 static const msi_table rf_tables[] =
2520 {
2521     ADD_TABLE(component),
2522     ADD_TABLE(directory),
2523     ADD_TABLE(feature),
2524     ADD_TABLE(feature_comp),
2525     ADD_TABLE(file),
2526     ADD_TABLE(cf_create_folders),
2527     ADD_TABLE(rf_install_exec_seq),
2528     ADD_TABLE(cf_custom_action),
2529     ADD_TABLE(media),
2530     ADD_TABLE(property)
2531 };
2532
2533 static const msi_table sss_tables[] =
2534 {
2535     ADD_TABLE(component),
2536     ADD_TABLE(directory),
2537     ADD_TABLE(feature),
2538     ADD_TABLE(feature_comp),
2539     ADD_TABLE(file),
2540     ADD_TABLE(sss_install_exec_seq),
2541     ADD_TABLE(sss_service_control),
2542     ADD_TABLE(media),
2543     ADD_TABLE(property)
2544 };
2545
2546 static const msi_table sds_tables[] =
2547 {
2548     ADD_TABLE(component),
2549     ADD_TABLE(directory),
2550     ADD_TABLE(feature),
2551     ADD_TABLE(feature_comp),
2552     ADD_TABLE(file),
2553     ADD_TABLE(sss_install_exec_seq),
2554     ADD_TABLE(service_control),
2555     ADD_TABLE(media),
2556     ADD_TABLE(property)
2557 };
2558
2559 static const msi_table sr_tables[] =
2560 {
2561     ADD_TABLE(component),
2562     ADD_TABLE(directory),
2563     ADD_TABLE(feature),
2564     ADD_TABLE(feature_comp),
2565     ADD_TABLE(file),
2566     ADD_TABLE(sr_selfreg),
2567     ADD_TABLE(sr_install_exec_seq),
2568     ADD_TABLE(media),
2569     ADD_TABLE(property)
2570 };
2571
2572 static const msi_table font_tables[] =
2573 {
2574     ADD_TABLE(font_component),
2575     ADD_TABLE(directory),
2576     ADD_TABLE(font_feature),
2577     ADD_TABLE(font_feature_comp),
2578     ADD_TABLE(font_file),
2579     ADD_TABLE(font),
2580     ADD_TABLE(font_install_exec_seq),
2581     ADD_TABLE(font_media),
2582     ADD_TABLE(property)
2583 };
2584
2585 static const msi_table vp_tables[] =
2586 {
2587     ADD_TABLE(component),
2588     ADD_TABLE(directory),
2589     ADD_TABLE(feature),
2590     ADD_TABLE(feature_comp),
2591     ADD_TABLE(file),
2592     ADD_TABLE(vp_custom_action),
2593     ADD_TABLE(vp_install_exec_seq),
2594     ADD_TABLE(media),
2595     ADD_TABLE(vp_property)
2596 };
2597
2598 static const msi_table odbc_tables[] =
2599 {
2600     ADD_TABLE(odbc_component),
2601     ADD_TABLE(directory),
2602     ADD_TABLE(odbc_feature),
2603     ADD_TABLE(odbc_feature_comp),
2604     ADD_TABLE(odbc_file),
2605     ADD_TABLE(odbc_driver),
2606     ADD_TABLE(odbc_translator),
2607     ADD_TABLE(odbc_datasource),
2608     ADD_TABLE(odbc_install_exec_seq),
2609     ADD_TABLE(odbc_media),
2610     ADD_TABLE(property)
2611 };
2612
2613 static const msi_table tl_tables[] =
2614 {
2615     ADD_TABLE(tl_component),
2616     ADD_TABLE(directory),
2617     ADD_TABLE(tl_feature),
2618     ADD_TABLE(tl_feature_comp),
2619     ADD_TABLE(tl_file),
2620     ADD_TABLE(tl_typelib),
2621     ADD_TABLE(tl_install_exec_seq),
2622     ADD_TABLE(media),
2623     ADD_TABLE(property)
2624 };
2625
2626 static const msi_table crs_tables[] =
2627 {
2628     ADD_TABLE(crs_component),
2629     ADD_TABLE(directory),
2630     ADD_TABLE(crs_feature),
2631     ADD_TABLE(crs_feature_comp),
2632     ADD_TABLE(crs_file),
2633     ADD_TABLE(crs_shortcut),
2634     ADD_TABLE(crs_install_exec_seq),
2635     ADD_TABLE(media),
2636     ADD_TABLE(property)
2637 };
2638
2639 static const msi_table pub_tables[] =
2640 {
2641     ADD_TABLE(directory),
2642     ADD_TABLE(pub_component),
2643     ADD_TABLE(pub_feature),
2644     ADD_TABLE(pub_feature_comp),
2645     ADD_TABLE(pub_file),
2646     ADD_TABLE(pub_publish_component),
2647     ADD_TABLE(pub_install_exec_seq),
2648     ADD_TABLE(media),
2649     ADD_TABLE(property)
2650 };
2651
2652 static const msi_table rd_tables[] =
2653 {
2654     ADD_TABLE(directory),
2655     ADD_TABLE(rd_component),
2656     ADD_TABLE(rd_feature),
2657     ADD_TABLE(rd_feature_comp),
2658     ADD_TABLE(rd_file),
2659     ADD_TABLE(rd_duplicate_file),
2660     ADD_TABLE(rd_install_exec_seq),
2661     ADD_TABLE(media),
2662     ADD_TABLE(property)
2663 };
2664
2665 static const msi_table rrv_tables[] =
2666 {
2667     ADD_TABLE(directory),
2668     ADD_TABLE(rrv_component),
2669     ADD_TABLE(rrv_feature),
2670     ADD_TABLE(rrv_feature_comp),
2671     ADD_TABLE(rrv_file),
2672     ADD_TABLE(rrv_registry),
2673     ADD_TABLE(rrv_remove_registry),
2674     ADD_TABLE(rrv_install_exec_seq),
2675     ADD_TABLE(media),
2676     ADD_TABLE(property)
2677 };
2678
2679 static const msi_table frp_tables[] =
2680 {
2681     ADD_TABLE(directory),
2682     ADD_TABLE(frp_component),
2683     ADD_TABLE(frp_feature),
2684     ADD_TABLE(frp_feature_comp),
2685     ADD_TABLE(frp_file),
2686     ADD_TABLE(frp_upgrade),
2687     ADD_TABLE(frp_custom_action),
2688     ADD_TABLE(frp_install_exec_seq),
2689     ADD_TABLE(media),
2690     ADD_TABLE(property)
2691 };
2692
2693 static const msi_table riv_tables[] =
2694 {
2695     ADD_TABLE(directory),
2696     ADD_TABLE(riv_component),
2697     ADD_TABLE(riv_feature),
2698     ADD_TABLE(riv_feature_comp),
2699     ADD_TABLE(riv_file),
2700     ADD_TABLE(riv_ini_file),
2701     ADD_TABLE(riv_remove_ini_file),
2702     ADD_TABLE(riv_install_exec_seq),
2703     ADD_TABLE(media),
2704     ADD_TABLE(property)
2705 };
2706
2707 static const msi_table res_tables[] =
2708 {
2709     ADD_TABLE(directory),
2710     ADD_TABLE(res_component),
2711     ADD_TABLE(res_feature),
2712     ADD_TABLE(res_feature_comp),
2713     ADD_TABLE(res_file),
2714     ADD_TABLE(res_environment),
2715     ADD_TABLE(res_install_exec_seq),
2716     ADD_TABLE(media),
2717     ADD_TABLE(property)
2718 };
2719
2720 static const msi_table rci_tables[] =
2721 {
2722     ADD_TABLE(directory),
2723     ADD_TABLE(rci_component),
2724     ADD_TABLE(rci_feature),
2725     ADD_TABLE(rci_feature_comp),
2726     ADD_TABLE(rci_file),
2727     ADD_TABLE(rci_appid),
2728     ADD_TABLE(rci_class),
2729     ADD_TABLE(rci_install_exec_seq),
2730     ADD_TABLE(media),
2731     ADD_TABLE(property)
2732 };
2733
2734 static const msi_table rei_tables[] =
2735 {
2736     ADD_TABLE(directory),
2737     ADD_TABLE(rei_component),
2738     ADD_TABLE(rei_feature),
2739     ADD_TABLE(rei_feature_comp),
2740     ADD_TABLE(rei_file),
2741     ADD_TABLE(rei_extension),
2742     ADD_TABLE(rei_verb),
2743     ADD_TABLE(rei_progid),
2744     ADD_TABLE(rei_install_exec_seq),
2745     ADD_TABLE(media),
2746     ADD_TABLE(property)
2747 };
2748
2749 /* cabinet definitions */
2750
2751 /* make the max size large so there is only one cab file */
2752 #define MEDIA_SIZE          0x7FFFFFFF
2753 #define FOLDER_THRESHOLD    900000
2754
2755 /* the FCI callbacks */
2756
2757 static void * CDECL mem_alloc(ULONG cb)
2758 {
2759     return HeapAlloc(GetProcessHeap(), 0, cb);
2760 }
2761
2762 static void CDECL mem_free(void *memory)
2763 {
2764     HeapFree(GetProcessHeap(), 0, memory);
2765 }
2766
2767 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
2768 {
2769     sprintf(pccab->szCab, pv, pccab->iCab);
2770     return TRUE;
2771 }
2772
2773 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
2774 {
2775     return 0;
2776 }
2777
2778 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
2779                              BOOL fContinuation, void *pv)
2780 {
2781     return 0;
2782 }
2783
2784 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
2785 {
2786     HANDLE handle;
2787     DWORD dwAccess = 0;
2788     DWORD dwShareMode = 0;
2789     DWORD dwCreateDisposition = OPEN_EXISTING;
2790     
2791     dwAccess = GENERIC_READ | GENERIC_WRITE;
2792     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
2793     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
2794
2795     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
2796         dwCreateDisposition = OPEN_EXISTING;
2797     else
2798         dwCreateDisposition = CREATE_NEW;
2799
2800     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
2801                          dwCreateDisposition, 0, NULL);
2802
2803     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
2804
2805     return (INT_PTR)handle;
2806 }
2807
2808 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2809 {
2810     HANDLE handle = (HANDLE)hf;
2811     DWORD dwRead;
2812     BOOL res;
2813     
2814     res = ReadFile(handle, memory, cb, &dwRead, NULL);
2815     ok(res, "Failed to ReadFile\n");
2816
2817     return dwRead;
2818 }
2819
2820 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2821 {
2822     HANDLE handle = (HANDLE)hf;
2823     DWORD dwWritten;
2824     BOOL res;
2825
2826     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
2827     ok(res, "Failed to WriteFile\n");
2828
2829     return dwWritten;
2830 }
2831
2832 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
2833 {
2834     HANDLE handle = (HANDLE)hf;
2835     ok(CloseHandle(handle), "Failed to CloseHandle\n");
2836
2837     return 0;
2838 }
2839
2840 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
2841 {
2842     HANDLE handle = (HANDLE)hf;
2843     DWORD ret;
2844     
2845     ret = SetFilePointer(handle, dist, NULL, seektype);
2846     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
2847
2848     return ret;
2849 }
2850
2851 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
2852 {
2853     BOOL ret = DeleteFileA(pszFile);
2854     ok(ret, "Failed to DeleteFile %s\n", pszFile);
2855
2856     return 0;
2857 }
2858
2859 static void init_functionpointers(void)
2860 {
2861     HMODULE hmsi = GetModuleHandleA("msi.dll");
2862     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
2863
2864 #define GET_PROC(mod, func) \
2865     p ## func = (void*)GetProcAddress(mod, #func); \
2866     if(!p ## func) \
2867       trace("GetProcAddress(%s) failed\n", #func);
2868
2869     GET_PROC(hmsi, MsiQueryComponentStateA);
2870     GET_PROC(hmsi, MsiSetExternalUIRecord);
2871     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
2872     GET_PROC(hmsi, MsiSourceListGetInfoA);
2873
2874     GET_PROC(hadvapi32, ConvertSidToStringSidA);
2875
2876     hsrclient = LoadLibraryA("srclient.dll");
2877     GET_PROC(hsrclient, SRRemoveRestorePoint);
2878     GET_PROC(hsrclient, SRSetRestorePointA);
2879
2880 #undef GET_PROC
2881 }
2882
2883 static BOOL check_win9x(void)
2884 {
2885     SC_HANDLE scm;
2886
2887     scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
2888     if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2889         return TRUE;
2890
2891     CloseServiceHandle(scm);
2892
2893     return FALSE;
2894 }
2895
2896 static LPSTR get_user_sid(LPSTR *usersid)
2897 {
2898     HANDLE token;
2899     BYTE buf[1024];
2900     DWORD size;
2901     PTOKEN_USER user;
2902
2903     if (!pConvertSidToStringSidA)
2904     {
2905         win_skip("ConvertSidToStringSidA is not available\n");
2906         return NULL;
2907     }
2908
2909     *usersid = NULL;
2910     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
2911     size = sizeof(buf);
2912     GetTokenInformation(token, TokenUser, buf, size, &size);
2913     user = (PTOKEN_USER)buf;
2914     pConvertSidToStringSidA(user->User.Sid, usersid);
2915     ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError());
2916     CloseHandle(token);
2917     return *usersid;
2918 }
2919
2920 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
2921 {
2922     CHAR buffer[0x20];
2923     UINT r;
2924     DWORD sz;
2925
2926     sz = sizeof buffer;
2927     r = MsiRecordGetString(rec, field, buffer, &sz);
2928     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
2929 }
2930
2931 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
2932 {
2933     LPSTR tempname;
2934
2935     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2936     GetTempFileNameA(".", "xx", 0, tempname);
2937
2938     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
2939     {
2940         lstrcpyA(pszTempName, tempname);
2941         HeapFree(GetProcessHeap(), 0, tempname);
2942         return TRUE;
2943     }
2944
2945     HeapFree(GetProcessHeap(), 0, tempname);
2946
2947     return FALSE;
2948 }
2949
2950 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
2951                                    USHORT *pattribs, int *err, void *pv)
2952 {
2953     BY_HANDLE_FILE_INFORMATION finfo;
2954     FILETIME filetime;
2955     HANDLE handle;
2956     DWORD attrs;
2957     BOOL res;
2958
2959     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
2960                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
2961
2962     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
2963
2964     res = GetFileInformationByHandle(handle, &finfo);
2965     ok(res, "Expected GetFileInformationByHandle to succeed\n");
2966    
2967     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
2968     FileTimeToDosDateTime(&filetime, pdate, ptime);
2969
2970     attrs = GetFileAttributes(pszName);
2971     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
2972
2973     return (INT_PTR)handle;
2974 }
2975
2976 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
2977 {
2978     char path[MAX_PATH];
2979     char filename[MAX_PATH];
2980
2981     lstrcpyA(path, CURR_DIR);
2982     lstrcatA(path, "\\");
2983     lstrcatA(path, file);
2984
2985     lstrcpyA(filename, file);
2986
2987     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
2988                       progress, get_open_info, compress);
2989 }
2990
2991 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
2992 {
2993     ZeroMemory(pCabParams, sizeof(CCAB));
2994
2995     pCabParams->cb = max_size;
2996     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
2997     pCabParams->setID = 0xbeef;
2998     pCabParams->iCab = 1;
2999     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
3000     lstrcatA(pCabParams->szCabPath, "\\");
3001     lstrcpyA(pCabParams->szCab, name);
3002 }
3003
3004 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
3005 {
3006     CCAB cabParams;
3007     LPCSTR ptr;
3008     HFCI hfci;
3009     ERF erf;
3010     BOOL res;
3011
3012     set_cab_parameters(&cabParams, name, max_size);
3013
3014     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
3015                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
3016                       get_temp_file, &cabParams, NULL);
3017
3018     ok(hfci != NULL, "Failed to create an FCI context\n");
3019
3020     ptr = files;
3021     while (*ptr)
3022     {
3023         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
3024         ok(res, "Failed to add file: %s\n", ptr);
3025         ptr += lstrlen(ptr) + 1;
3026     }
3027
3028     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
3029     ok(res, "Failed to flush the cabinet\n");
3030
3031     res = FCIDestroy(hfci);
3032     ok(res, "Failed to destroy the cabinet\n");
3033 }
3034
3035 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
3036 {
3037     HKEY hkey;
3038     DWORD type, size;
3039
3040     if (RegOpenKey(HKEY_LOCAL_MACHINE,
3041                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
3042         return FALSE;
3043
3044     size = MAX_PATH;
3045     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
3046         RegCloseKey(hkey);
3047         return FALSE;
3048     }
3049
3050     size = MAX_PATH;
3051     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
3052         RegCloseKey(hkey);
3053         return FALSE;
3054     }
3055
3056     RegCloseKey(hkey);
3057     return TRUE;
3058 }
3059
3060 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
3061 {
3062     HANDLE file;
3063     DWORD written;
3064
3065     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
3066     if (file == INVALID_HANDLE_VALUE)
3067         return;
3068
3069     WriteFile(file, data, strlen(data), &written, NULL);
3070
3071     if (size)
3072     {
3073         SetFilePointer(file, size, NULL, FILE_BEGIN);
3074         SetEndOfFile(file);
3075     }
3076
3077     CloseHandle(file);
3078 }
3079
3080 #define create_file(name, size) create_file_data(name, name, size)
3081
3082 static void create_test_files(void)
3083 {
3084     CreateDirectoryA("msitest", NULL);
3085     create_file("msitest\\one.txt", 100);
3086     CreateDirectoryA("msitest\\first", NULL);
3087     create_file("msitest\\first\\two.txt", 100);
3088     CreateDirectoryA("msitest\\second", NULL);
3089     create_file("msitest\\second\\three.txt", 100);
3090
3091     create_file("four.txt", 100);
3092     create_file("five.txt", 100);
3093     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
3094
3095     create_file("msitest\\filename", 100);
3096     create_file("msitest\\service.exe", 100);
3097
3098     DeleteFileA("four.txt");
3099     DeleteFileA("five.txt");
3100 }
3101
3102 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
3103 {
3104     CHAR path[MAX_PATH];
3105
3106     lstrcpyA(path, PROG_FILES_DIR);
3107     lstrcatA(path, "\\");
3108     lstrcatA(path, rel_path);
3109
3110     if (is_file)
3111         return DeleteFileA(path);
3112     else
3113         return RemoveDirectoryA(path);
3114 }
3115
3116 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
3117 {
3118     CHAR path[MAX_PATH];
3119
3120     lstrcpyA(path, COMMON_FILES_DIR);
3121     lstrcatA(path, "\\");
3122     lstrcatA(path, rel_path);
3123
3124     if (is_file)
3125         return DeleteFileA(path);
3126     else
3127         return RemoveDirectoryA(path);
3128 }
3129
3130 static void delete_test_files(void)
3131 {
3132     DeleteFileA("msitest.msi");
3133     DeleteFileA("msitest.cab");
3134     DeleteFileA("msitest\\second\\three.txt");
3135     DeleteFileA("msitest\\first\\two.txt");
3136     DeleteFileA("msitest\\one.txt");
3137     DeleteFileA("msitest\\service.exe");
3138     DeleteFileA("msitest\\filename");
3139     RemoveDirectoryA("msitest\\second");
3140     RemoveDirectoryA("msitest\\first");
3141     RemoveDirectoryA("msitest");
3142 }
3143
3144 static void write_file(const CHAR *filename, const char *data, int data_size)
3145 {
3146     DWORD size;
3147
3148     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
3149                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3150
3151     WriteFile(hf, data, data_size, &size, NULL);
3152     CloseHandle(hf);
3153 }
3154
3155 static void write_msi_summary_info(MSIHANDLE db, INT wordcount)
3156 {
3157     MSIHANDLE summary;
3158     UINT r;
3159
3160     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
3161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3162
3163     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
3164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3165
3166     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3167                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
3168     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3169
3170     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3171     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3172
3173     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
3174     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3175
3176     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3178
3179     /* write the summary changes back to the stream */
3180     r = MsiSummaryInfoPersist(summary);
3181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3182
3183     MsiCloseHandle(summary);
3184 }
3185
3186 #define create_database(name, tables, num_tables) \
3187     create_database_wordcount(name, tables, num_tables, 0);
3188
3189 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
3190                                       int num_tables, INT wordcount)
3191 {
3192     MSIHANDLE db;
3193     UINT r;
3194     int j;
3195
3196     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
3197     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3198
3199     /* import the tables into the database */
3200     for (j = 0; j < num_tables; j++)
3201     {
3202         const msi_table *table = &tables[j];
3203
3204         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
3205
3206         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
3207         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3208
3209         DeleteFileA(table->filename);
3210     }
3211
3212     write_msi_summary_info(db, wordcount);
3213
3214     r = MsiDatabaseCommit(db);
3215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3216
3217     MsiCloseHandle(db);
3218 }
3219
3220 static void check_service_is_installed(void)
3221 {
3222     SC_HANDLE scm, service;
3223     BOOL res;
3224
3225     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
3226     ok(scm != NULL, "Failed to open the SC Manager\n");
3227
3228     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
3229     ok(service != NULL, "Failed to open TestService\n");
3230
3231     res = DeleteService(service);
3232     ok(res, "Failed to delete TestService\n");
3233
3234     CloseServiceHandle(service);
3235     CloseServiceHandle(scm);
3236 }
3237
3238 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
3239 {
3240     RESTOREPOINTINFOA spec;
3241
3242     spec.dwEventType = event_type;
3243     spec.dwRestorePtType = APPLICATION_INSTALL;
3244     spec.llSequenceNumber = status->llSequenceNumber;
3245     lstrcpyA(spec.szDescription, "msitest restore point");
3246
3247     return pSRSetRestorePointA(&spec, status);
3248 }
3249
3250 static void remove_restore_point(DWORD seq_number)
3251 {
3252     DWORD res;
3253
3254     res = pSRRemoveRestorePoint(seq_number);
3255     if (res != ERROR_SUCCESS)
3256         trace("Failed to remove the restore point : %08x\n", res);
3257 }
3258
3259 static void test_MsiInstallProduct(void)
3260 {
3261     UINT r;
3262     CHAR path[MAX_PATH];
3263     LONG res;
3264     HKEY hkey;
3265     DWORD num, size, type;
3266
3267     if (on_win9x)
3268     {
3269         win_skip("Services are not implemented on Win9x and WinMe\n");
3270         return;
3271     }
3272
3273     /* szPackagePath is NULL */
3274     r = MsiInstallProductA(NULL, "INSTALL=ALL");
3275     ok(r == ERROR_INVALID_PARAMETER,
3276        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3277
3278     /* both szPackagePath and szCommandLine are NULL */
3279     r = MsiInstallProductA(NULL, NULL);
3280     ok(r == ERROR_INVALID_PARAMETER,
3281        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3282
3283     /* szPackagePath is empty */
3284     r = MsiInstallProductA("", "INSTALL=ALL");
3285     ok(r == ERROR_PATH_NOT_FOUND,
3286        "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
3287
3288     create_test_files();
3289     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3290
3291     /* install, don't publish */
3292     r = MsiInstallProductA(msifile, NULL);
3293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3294
3295     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3296     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3297     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3298     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3299     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3300     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3301     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3302     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3303     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3304     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3305     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3306     ok(delete_pf("msitest", FALSE), "File not installed\n");
3307
3308     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3310
3311     size = MAX_PATH;
3312     type = REG_SZ;
3313     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
3314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3315     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
3316
3317     size = MAX_PATH;
3318     type = REG_SZ;
3319     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
3320     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3321
3322     size = sizeof(num);
3323     type = REG_DWORD;
3324     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
3325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3326     ok(num == 314, "Expected 314, got %d\n", num);
3327
3328     size = MAX_PATH;
3329     type = REG_SZ;
3330     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
3331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3332     ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
3333
3334     check_service_is_installed();
3335
3336     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3337
3338     /* not published, reinstall */
3339     r = MsiInstallProductA(msifile, NULL);
3340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3341
3342     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3343     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3344     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3345     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3346     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3347     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3348     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3349     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3350     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3351     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3352     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3353     ok(delete_pf("msitest", FALSE), "File not installed\n");
3354
3355     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3357     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3358
3359     create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table));
3360
3361     /* not published, RemovePreviousVersions set */
3362     r = MsiInstallProductA(msifile, NULL);
3363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3364
3365     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3366     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3367     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3368     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3369     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3370     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3371     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3372     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3373     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3374     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3375     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3376     ok(delete_pf("msitest", FALSE), "File not installed\n");
3377
3378     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3380     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3381
3382     create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table));
3383
3384     /* not published, version number bumped */
3385     r = MsiInstallProductA(msifile, NULL);
3386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3387
3388     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3389     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3390     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3391     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3392     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3393     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3394     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3395     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3396     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3397     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3398     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3399     ok(delete_pf("msitest", FALSE), "File not installed\n");
3400
3401     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3403     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3404
3405     create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table));
3406
3407     /* not published, RemovePreviousVersions set and version number bumped */
3408     r = MsiInstallProductA(msifile, NULL);
3409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3410
3411     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3412     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3413     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3414     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3415     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3416     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3417     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3418     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3419     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3420     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3421     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3422     ok(delete_pf("msitest", FALSE), "File not installed\n");
3423
3424     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3426     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3427
3428     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3429
3430     /* install, publish product */
3431     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3433
3434     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3435     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3436     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3437     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3438     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3439     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3440     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3441     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3442     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3443     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3444     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3445     ok(delete_pf("msitest", FALSE), "File not installed\n");
3446
3447     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3448     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3449
3450     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3451
3452     /* published, reinstall */
3453     r = MsiInstallProductA(msifile, NULL);
3454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3455
3456     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3457     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3458     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3459     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3460     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3461     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3462     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3463     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3464     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3465     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3466     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3467     ok(delete_pf("msitest", FALSE), "File not installed\n");
3468
3469     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3470     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3471
3472     create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table));
3473
3474     /* published product, RemovePreviousVersions set */
3475     r = MsiInstallProductA(msifile, NULL);
3476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3477
3478     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3479     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3480     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3481     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3482     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3483     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3484     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3485     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3486     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3487     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3488     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3489     ok(delete_pf("msitest", FALSE), "File not installed\n");
3490
3491     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3492     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3493
3494     create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table));
3495
3496     /* published product, version number bumped */
3497     r = MsiInstallProductA(msifile, NULL);
3498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3499
3500     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3501     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3502     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3503     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3504     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3505     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3506     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3507     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3508     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3509     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3510     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3511     ok(delete_pf("msitest", FALSE), "File not installed\n");
3512
3513     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3514     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3515
3516     create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table));
3517
3518     /* published product, RemovePreviousVersions set and version number bumped */
3519     r = MsiInstallProductA(msifile, NULL);
3520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3521
3522     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3523     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3524     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3525     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3526     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3527     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3528     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3529     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3530     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3531     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3532     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3533     ok(delete_pf("msitest", FALSE), "File not installed\n");
3534
3535     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3536     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3537
3538     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3540
3541     delete_test_files();
3542 }
3543
3544 static void test_MsiSetComponentState(void)
3545 {
3546     INSTALLSTATE installed, action;
3547     MSIHANDLE package;
3548     char path[MAX_PATH];
3549     UINT r;
3550
3551     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3552
3553     CoInitialize(NULL);
3554
3555     lstrcpy(path, CURR_DIR);
3556     lstrcat(path, "\\");
3557     lstrcat(path, msifile);
3558
3559     r = MsiOpenPackage(path, &package);
3560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3561
3562     r = MsiDoAction(package, "CostInitialize");
3563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3564
3565     r = MsiDoAction(package, "FileCost");
3566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3567
3568     r = MsiDoAction(package, "CostFinalize");
3569     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3570
3571     r = MsiGetComponentState(package, "dangler", &installed, &action);
3572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3573     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
3574     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
3575
3576     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
3577     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3578
3579     MsiCloseHandle(package);
3580     CoUninitialize();
3581
3582     DeleteFileA(msifile);
3583 }
3584
3585 static void test_packagecoltypes(void)
3586 {
3587     MSIHANDLE hdb, view, rec;
3588     char path[MAX_PATH];
3589     LPCSTR query;
3590     UINT r, count;
3591
3592     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3593
3594     CoInitialize(NULL);
3595
3596     lstrcpy(path, CURR_DIR);
3597     lstrcat(path, "\\");
3598     lstrcat(path, msifile);
3599
3600     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
3601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3602
3603     query = "SELECT * FROM `Media`";
3604     r = MsiDatabaseOpenView( hdb, query, &view );
3605     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3606
3607     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
3608     count = MsiRecordGetFieldCount( rec );
3609     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3610     ok(count == 6, "Expected 6, got %d\n", count);
3611     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
3612     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
3613     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
3614     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
3615     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
3616     ok(check_record(rec, 6, "Source"), "wrong column label\n");
3617     MsiCloseHandle(rec);
3618
3619     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
3620     count = MsiRecordGetFieldCount( rec );
3621     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3622     ok(count == 6, "Expected 6, got %d\n", count);
3623     ok(check_record(rec, 1, "i2"), "wrong column label\n");
3624     ok(check_record(rec, 2, "i4"), "wrong column label\n");
3625     ok(check_record(rec, 3, "L64"), "wrong column label\n");
3626     ok(check_record(rec, 4, "S255"), "wrong column label\n");
3627     ok(check_record(rec, 5, "S32"), "wrong column label\n");
3628     ok(check_record(rec, 6, "S72"), "wrong column label\n");
3629
3630     MsiCloseHandle(rec);
3631     MsiCloseHandle(view);
3632     MsiCloseHandle(hdb);
3633     CoUninitialize();
3634
3635     DeleteFile(msifile);
3636 }
3637
3638 static void create_cc_test_files(void)
3639 {
3640     CCAB cabParams;
3641     HFCI hfci;
3642     ERF erf;
3643     static CHAR cab_context[] = "test%d.cab";
3644     BOOL res;
3645
3646     create_file("maximus", 500);
3647     create_file("augustus", 50000);
3648     create_file("tiberius", 500);
3649     create_file("caesar", 500);
3650
3651     set_cab_parameters(&cabParams, "test1.cab", 40000);
3652
3653     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
3654                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
3655                       get_temp_file, &cabParams, cab_context);
3656     ok(hfci != NULL, "Failed to create an FCI context\n");
3657
3658     res = add_file(hfci, "maximus", tcompTYPE_NONE);
3659     ok(res, "Failed to add file maximus\n");
3660
3661     res = add_file(hfci, "augustus", tcompTYPE_NONE);
3662     ok(res, "Failed to add file augustus\n");
3663
3664     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
3665     ok(res, "Failed to add file tiberius\n");
3666
3667     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
3668     ok(res, "Failed to flush the cabinet\n");
3669
3670     res = FCIDestroy(hfci);
3671     ok(res, "Failed to destroy the cabinet\n");
3672
3673     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3674
3675     DeleteFile("maximus");
3676     DeleteFile("augustus");
3677     DeleteFile("tiberius");
3678     DeleteFile("caesar");
3679 }
3680
3681 static void delete_cab_files(void)
3682 {
3683     SHFILEOPSTRUCT shfl;
3684     CHAR path[MAX_PATH+10];
3685
3686     lstrcpyA(path, CURR_DIR);
3687     lstrcatA(path, "\\*.cab");
3688     path[strlen(path) + 1] = '\0';
3689
3690     shfl.hwnd = NULL;
3691     shfl.wFunc = FO_DELETE;
3692     shfl.pFrom = path;
3693     shfl.pTo = NULL;
3694     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
3695
3696     SHFileOperation(&shfl);
3697 }
3698
3699 static void test_continuouscabs(void)
3700 {
3701     UINT r;
3702
3703     create_cc_test_files();
3704     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3705
3706     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3707
3708     r = MsiInstallProductA(msifile, NULL);
3709     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3710     {
3711         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3712         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3713         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3714         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3715         ok(delete_pf("msitest", FALSE), "File not installed\n");
3716     }
3717
3718     delete_cab_files();
3719     DeleteFile(msifile);
3720
3721     create_cc_test_files();
3722     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
3723
3724     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3725
3726     r = MsiInstallProductA(msifile, NULL);
3727     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3728     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3729     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3730     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
3731     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3732     ok(delete_pf("msitest", FALSE), "File not installed\n");
3733
3734     delete_cab_files();
3735     DeleteFile(msifile);
3736 }
3737
3738 static void test_caborder(void)
3739 {
3740     UINT r;
3741
3742     create_file("imperator", 100);
3743     create_file("maximus", 500);
3744     create_file("augustus", 50000);
3745     create_file("caesar", 500);
3746
3747     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3748
3749     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3750
3751     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3752     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3753     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3754
3755     r = MsiInstallProductA(msifile, NULL);
3756     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3757     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3758     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3759     todo_wine
3760     {
3761         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3762         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3763     }
3764
3765     delete_cab_files();
3766
3767     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
3768     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
3769     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3770
3771     r = MsiInstallProductA(msifile, NULL);
3772     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3773     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3774     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3775     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3776     todo_wine
3777     {
3778         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3779     }
3780
3781     delete_cab_files();
3782     DeleteFile(msifile);
3783
3784     create_cc_test_files();
3785     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
3786
3787     r = MsiInstallProductA(msifile, NULL);
3788     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3789     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3790     ok(!delete_pf("msitest", FALSE), "File is installed\n");
3791     todo_wine
3792     {
3793         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3794         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3795     }
3796
3797     delete_cab_files();
3798     DeleteFile(msifile);
3799
3800     create_cc_test_files();
3801     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
3802
3803     r = MsiInstallProductA(msifile, NULL);
3804     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3805     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3806     todo_wine
3807     {
3808         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3809         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3810         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3811     }
3812
3813     delete_cab_files();
3814     DeleteFile("imperator");
3815     DeleteFile("maximus");
3816     DeleteFile("augustus");
3817     DeleteFile("caesar");
3818     DeleteFile(msifile);
3819 }
3820
3821 static void test_mixedmedia(void)
3822 {
3823     UINT r;
3824
3825     CreateDirectoryA("msitest", NULL);
3826     create_file("msitest\\maximus", 500);
3827     create_file("msitest\\augustus", 500);
3828     create_file("caesar", 500);
3829
3830     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
3831
3832     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3833
3834     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
3835
3836     r = MsiInstallProductA(msifile, NULL);
3837     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3838     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3839     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3840     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3841     ok(delete_pf("msitest", FALSE), "File not installed\n");
3842
3843     /* Delete the files in the temp (current) folder */
3844     DeleteFile("msitest\\maximus");
3845     DeleteFile("msitest\\augustus");
3846     RemoveDirectory("msitest");
3847     DeleteFile("caesar");
3848     DeleteFile("test1.cab");
3849     DeleteFile(msifile);
3850 }
3851
3852 static void test_samesequence(void)
3853 {
3854     UINT r;
3855
3856     create_cc_test_files();
3857     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
3858
3859     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3860
3861     r = MsiInstallProductA(msifile, NULL);
3862     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3863     {
3864         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3865         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3866         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3867         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3868         ok(delete_pf("msitest", FALSE), "File not installed\n");
3869     }
3870
3871     delete_cab_files();
3872     DeleteFile(msifile);
3873 }
3874
3875 static void test_uiLevelFlags(void)
3876 {
3877     UINT r;
3878
3879     create_cc_test_files();
3880     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
3881
3882     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
3883
3884     r = MsiInstallProductA(msifile, NULL);
3885     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3886     {
3887         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3888         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
3889         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3890         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3891         ok(delete_pf("msitest", FALSE), "File not installed\n");
3892     }
3893
3894     delete_cab_files();
3895     DeleteFile(msifile);
3896 }
3897
3898 static BOOL file_matches(LPSTR path)
3899 {
3900     CHAR buf[MAX_PATH];
3901     HANDLE file;
3902     DWORD size;
3903
3904     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3905                       NULL, OPEN_EXISTING, 0, NULL);
3906
3907     ZeroMemory(buf, MAX_PATH);
3908     ReadFile(file, buf, 15, &size, NULL);
3909     CloseHandle(file);
3910
3911     return !lstrcmp(buf, "msitest\\maximus");
3912 }
3913
3914 static void test_readonlyfile(void)
3915 {
3916     UINT r;
3917     DWORD size;
3918     HANDLE file;
3919     CHAR path[MAX_PATH];
3920
3921     CreateDirectoryA("msitest", NULL);
3922     create_file("msitest\\maximus", 500);
3923     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
3924
3925     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3926
3927     lstrcpy(path, PROG_FILES_DIR);
3928     lstrcat(path, "\\msitest");
3929     CreateDirectory(path, NULL);
3930
3931     lstrcat(path, "\\maximus");
3932     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3933                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3934
3935     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3936     CloseHandle(file);
3937
3938     r = MsiInstallProductA(msifile, NULL);
3939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3940     ok(file_matches(path), "Expected file to be overwritten\n");
3941     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3942     ok(delete_pf("msitest", FALSE), "File not installed\n");
3943
3944     /* Delete the files in the temp (current) folder */
3945     DeleteFile("msitest\\maximus");
3946     RemoveDirectory("msitest");
3947     DeleteFile(msifile);
3948 }
3949
3950 static void test_readonlyfile_cab(void)
3951 {
3952     UINT r;
3953     DWORD size;
3954     HANDLE file;
3955     CHAR path[MAX_PATH];
3956     CHAR buf[16];
3957
3958     CreateDirectoryA("msitest", NULL);
3959     create_file("maximus", 500);
3960     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3961     DeleteFile("maximus");
3962
3963     create_database(msifile, rofc_tables, sizeof(rofc_tables) / sizeof(msi_table));
3964
3965     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3966
3967     lstrcpy(path, PROG_FILES_DIR);
3968     lstrcat(path, "\\msitest");
3969     CreateDirectory(path, NULL);
3970
3971     lstrcat(path, "\\maximus");
3972     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3973                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
3974
3975     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
3976     CloseHandle(file);
3977
3978     r = MsiInstallProductA(msifile, NULL);
3979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3980
3981     memset( buf, 0, sizeof(buf) );
3982     if ((file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3983                            NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
3984     {
3985         ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
3986         CloseHandle(file);
3987     }
3988     ok(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "Expected file to be overwritten, got '%s'\n", buf);
3989     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3990     ok(delete_pf("msitest", FALSE), "File not installed\n");
3991
3992     /* Delete the files in the temp (current) folder */
3993     delete_cab_files();
3994     DeleteFile("msitest\\maximus");
3995     RemoveDirectory("msitest");
3996     DeleteFile(msifile);
3997 }
3998
3999 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
4000 {
4001     WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
4002     IStorage *stg;
4003     IStream *stm;
4004     HRESULT hr;
4005     HANDLE handle;
4006
4007     MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
4008     hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
4009     if (FAILED(hr))
4010         return FALSE;
4011
4012     MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
4013     hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4014     if (FAILED(hr))
4015     {
4016         IStorage_Release(stg);
4017         return FALSE;
4018     }
4019
4020     handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
4021     if (handle != INVALID_HANDLE_VALUE)
4022     {
4023         DWORD count;
4024         char buffer[1024];
4025         if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
4026             IStream_Write(stm, buffer, count, &count);
4027         CloseHandle(handle);
4028     }
4029
4030     IStream_Release(stm);
4031     IStorage_Release(stg);
4032
4033     return TRUE;
4034 }
4035
4036 static void test_lastusedsource(void)
4037 {
4038     static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4039
4040     UINT r;
4041     char value[MAX_PATH], path[MAX_PATH];
4042     DWORD size;
4043
4044     if (!pMsiSourceListGetInfoA)
4045     {
4046         win_skip("MsiSourceListGetInfoA is not available\n");
4047         return;
4048     }
4049
4050     CreateDirectoryA("msitest", NULL);
4051     create_file("maximus", 500);
4052     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4053     DeleteFile("maximus");
4054
4055     create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
4056     create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
4057     create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
4058
4059     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4060
4061     /* no cabinet file */
4062
4063     size = MAX_PATH;
4064     lstrcpyA(value, "aaa");
4065     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4066                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4067     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4068     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4069
4070     r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
4071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4072
4073     lstrcpyA(path, CURR_DIR);
4074     lstrcatA(path, "\\");
4075
4076     size = MAX_PATH;
4077     lstrcpyA(value, "aaa");
4078     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4079                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4080     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4081     todo_wine
4082     {
4083     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4084     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4085     }
4086
4087     r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
4088     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4089
4090     /* separate cabinet file */
4091
4092     size = MAX_PATH;
4093     lstrcpyA(value, "aaa");
4094     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4095                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4096     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4097     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4098
4099     r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
4100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4101
4102     lstrcpyA(path, CURR_DIR);
4103     lstrcatA(path, "\\");
4104
4105     size = MAX_PATH;
4106     lstrcpyA(value, "aaa");
4107     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4108                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4109     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4110     todo_wine
4111     {
4112     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4113     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4114     }
4115
4116     r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
4117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4118
4119     size = MAX_PATH;
4120     lstrcpyA(value, "aaa");
4121     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4122                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4123     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4124     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4125
4126     /* embedded cabinet stream */
4127
4128     add_cabinet_storage("msifile2.msi", "test1.cab");
4129
4130     r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
4131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4132
4133     size = MAX_PATH;
4134     lstrcpyA(value, "aaa");
4135     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4136                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4138     todo_wine
4139     {
4140     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4141     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4142     }
4143
4144     r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
4145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4146
4147     size = MAX_PATH;
4148     lstrcpyA(value, "aaa");
4149     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4150                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4151     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4152     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4153
4154     /* Delete the files in the temp (current) folder */
4155     delete_cab_files();
4156     DeleteFile("msitest\\maximus");
4157     RemoveDirectory("msitest");
4158     DeleteFile("msifile0.msi");
4159     DeleteFile("msifile1.msi");
4160     DeleteFile("msifile2.msi");
4161 }
4162
4163 static void test_setdirproperty(void)
4164 {
4165     UINT r;
4166
4167     CreateDirectoryA("msitest", NULL);
4168     create_file("msitest\\maximus", 500);
4169     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
4170
4171     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4172
4173     r = MsiInstallProductA(msifile, NULL);
4174     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4175     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
4176     ok(delete_cf("msitest", FALSE), "File not installed\n");
4177
4178     /* Delete the files in the temp (current) folder */
4179     DeleteFile(msifile);
4180     DeleteFile("msitest\\maximus");
4181     RemoveDirectory("msitest");
4182 }
4183
4184 static void test_cabisextracted(void)
4185 {
4186     UINT r;
4187
4188     CreateDirectoryA("msitest", NULL);
4189     create_file("msitest\\gaius", 500);
4190     create_file("maximus", 500);
4191     create_file("augustus", 500);
4192     create_file("caesar", 500);
4193
4194     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4195     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
4196     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
4197
4198     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
4199
4200     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4201
4202     r = MsiInstallProductA(msifile, NULL);
4203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4204     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4205     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4206     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4207     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
4208     ok(delete_pf("msitest", FALSE), "File not installed\n");
4209
4210     /* Delete the files in the temp (current) folder */
4211     delete_cab_files();
4212     DeleteFile(msifile);
4213     DeleteFile("maximus");
4214     DeleteFile("augustus");
4215     DeleteFile("caesar");
4216     DeleteFile("msitest\\gaius");
4217     RemoveDirectory("msitest");
4218 }
4219
4220 static void test_concurrentinstall(void)
4221 {
4222     UINT r;
4223     CHAR path[MAX_PATH];
4224
4225     CreateDirectoryA("msitest", NULL);
4226     CreateDirectoryA("msitest\\msitest", NULL);
4227     create_file("msitest\\maximus", 500);
4228     create_file("msitest\\msitest\\augustus", 500);
4229
4230     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
4231
4232     lstrcpyA(path, CURR_DIR);
4233     lstrcatA(path, "\\msitest\\concurrent.msi");
4234     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
4235
4236     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4237
4238     r = MsiInstallProductA(msifile, NULL);
4239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4240     if (!delete_pf("msitest\\augustus", TRUE))
4241         trace("concurrent installs not supported\n");
4242     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4243     ok(delete_pf("msitest", FALSE), "File not installed\n");
4244
4245     DeleteFile(path);
4246
4247     r = MsiInstallProductA(msifile, NULL);
4248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4249     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4250     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4251     ok(delete_pf("msitest", FALSE), "File not installed\n");
4252
4253     DeleteFile(msifile);
4254     DeleteFile("msitest\\msitest\\augustus");
4255     DeleteFile("msitest\\maximus");
4256     RemoveDirectory("msitest\\msitest");
4257     RemoveDirectory("msitest");
4258 }
4259
4260 static void test_setpropertyfolder(void)
4261 {
4262     UINT r;
4263     CHAR path[MAX_PATH];
4264     DWORD attr;
4265
4266     lstrcpyA(path, PROG_FILES_DIR);
4267     lstrcatA(path, "\\msitest\\added");
4268
4269     CreateDirectoryA("msitest", NULL);
4270     create_file("msitest\\maximus", 500);
4271
4272     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
4273
4274     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4275
4276     r = MsiInstallProductA(msifile, NULL);
4277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4278     attr = GetFileAttributesA(path);
4279     if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
4280     {
4281         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
4282         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
4283         ok(delete_pf("msitest", FALSE), "File not installed\n");
4284     }
4285     else
4286     {
4287         trace("changing folder property not supported\n");
4288         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4289         ok(delete_pf("msitest", FALSE), "File not installed\n");
4290     }
4291
4292     /* Delete the files in the temp (current) folder */
4293     DeleteFile(msifile);
4294     DeleteFile("msitest\\maximus");
4295     RemoveDirectory("msitest");
4296 }
4297
4298 static BOOL file_exists(LPCSTR file)
4299 {
4300     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
4301 }
4302
4303 static BOOL pf_exists(LPCSTR file)
4304 {
4305     CHAR path[MAX_PATH];
4306
4307     lstrcpyA(path, PROG_FILES_DIR);
4308     lstrcatA(path, "\\");
4309     lstrcatA(path, file);
4310
4311     return file_exists(path);
4312 }
4313
4314 static void delete_pfmsitest_files(void)
4315 {
4316     SHFILEOPSTRUCT shfl;
4317     CHAR path[MAX_PATH+11];
4318
4319     lstrcpyA(path, PROG_FILES_DIR);
4320     lstrcatA(path, "\\msitest\\*");
4321     path[strlen(path) + 1] = '\0';
4322
4323     shfl.hwnd = NULL;
4324     shfl.wFunc = FO_DELETE;
4325     shfl.pFrom = path;
4326     shfl.pTo = NULL;
4327     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
4328
4329     SHFileOperation(&shfl);
4330
4331     lstrcpyA(path, PROG_FILES_DIR);
4332     lstrcatA(path, "\\msitest");
4333     RemoveDirectoryA(path);
4334 }
4335
4336 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
4337 {
4338     char val[MAX_PATH];
4339     DWORD size, type;
4340     LONG res;
4341
4342     size = MAX_PATH;
4343     val[0] = '\0';
4344     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
4345
4346     if (res != ERROR_SUCCESS ||
4347         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
4348     {
4349         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4350         return;
4351     }
4352
4353     if (!expected)
4354         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
4355     else
4356     {
4357         if (bcase)
4358             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
4359         else
4360             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
4361     }
4362 }
4363
4364 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
4365 {
4366     DWORD val, size, type;
4367     LONG res;
4368
4369     size = sizeof(DWORD);
4370     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4371
4372     if (res != ERROR_SUCCESS || type != REG_DWORD)
4373     {
4374         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4375         return;
4376     }
4377
4378     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
4379 }
4380
4381 static void check_reg_dword2(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD line)
4382 {
4383     DWORD val, size, type;
4384     LONG res;
4385
4386     size = sizeof(DWORD);
4387     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4388
4389     if (res != ERROR_SUCCESS || type != REG_DWORD)
4390     {
4391         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4392         return;
4393     }
4394
4395     ok_(__FILE__, line)(val == expected1 || val == expected2, "Expected %d or %d, got %d\n", expected1, expected2, val);
4396 }
4397
4398 static void check_reg_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line)
4399 {
4400     DWORD val, size, type;
4401     LONG res;
4402
4403     size = sizeof(DWORD);
4404     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4405
4406     if (res != ERROR_SUCCESS || type != REG_DWORD)
4407     {
4408         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4409         return;
4410     }
4411
4412     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3,
4413                         "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val);
4414 }
4415
4416 #define CHECK_REG_STR(prodkey, name, expected) \
4417     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
4418
4419 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
4420     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
4421     RegDeleteValueA(prodkey, name);
4422
4423 #define CHECK_REG_ISTR(prodkey, name, expected) \
4424     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
4425
4426 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
4427     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
4428     RegDeleteValueA(prodkey, name);
4429
4430 #define CHECK_REG_DWORD(prodkey, name, expected) \
4431     check_reg_dword(prodkey, name, expected, __LINE__);
4432
4433 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
4434     check_reg_dword(prodkey, name, expected, __LINE__); \
4435     RegDeleteValueA(prodkey, name);
4436
4437 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
4438     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
4439
4440 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
4441     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
4442     RegDeleteValueA(prodkey, name);
4443
4444 #define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4445     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__);
4446
4447 #define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4448     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \
4449     RegDeleteValueA(prodkey, name);
4450
4451 static void get_date_str(LPSTR date)
4452 {
4453     SYSTEMTIME systime;
4454
4455     static const char date_fmt[] = "%d%02d%02d";
4456     GetLocalTime(&systime);
4457     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
4458 }
4459
4460 static void test_publish_registerproduct(void)
4461 {
4462     UINT r;
4463     LONG res;
4464     HKEY hkey;
4465     HKEY props, usage;
4466     LPSTR usersid;
4467     char date[MAX_PATH];
4468     char temp[MAX_PATH];
4469     char keypath[MAX_PATH];
4470
4471     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4472                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4473     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4474                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4475     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4476                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4477     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4478                                     "\\51AAE0C44620A5E4788506E91F249BD2";
4479
4480     if (!get_user_sid(&usersid))
4481         return;
4482
4483     get_date_str(date);
4484     GetTempPath(MAX_PATH, temp);
4485
4486     CreateDirectoryA("msitest", NULL);
4487     create_file("msitest\\maximus", 500);
4488
4489     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4490
4491     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4492
4493     /* RegisterProduct */
4494     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4495     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4496     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4497     ok(delete_pf("msitest", FALSE), "File not installed\n");
4498
4499     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
4500     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4501
4502     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4504
4505     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4506     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4507     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4508     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4509     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4510     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4511     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4512     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4513     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4514     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4515     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4516     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4517     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4518     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4519     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4520     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4521     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4522     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4523     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4524     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4525     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4526     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4527     todo_wine
4528     {
4529         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4530     }
4531
4532     RegDeleteKeyA(hkey, "");
4533     RegCloseKey(hkey);
4534
4535     sprintf(keypath, userdata, usersid);
4536     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4538
4539     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4541
4542     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4543     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4544     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4545     CHECK_DEL_REG_STR(props, "InstallDate", date);
4546     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4547     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4548     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4549     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4550     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4551     CHECK_DEL_REG_STR(props, "Comments", NULL);
4552     CHECK_DEL_REG_STR(props, "Contact", NULL);
4553     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4554     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4555     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4556     CHECK_DEL_REG_STR(props, "Readme", NULL);
4557     CHECK_DEL_REG_STR(props, "Size", NULL);
4558     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4559     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4560     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4561     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4562     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4563     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4564     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4565     todo_wine
4566     {
4567         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4568     }
4569
4570     RegDeleteKeyA(props, "");
4571     RegCloseKey(props);
4572
4573     res = RegOpenKeyA(hkey, "Usage", &usage);
4574     todo_wine
4575     {
4576         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4577     }
4578
4579     RegDeleteKeyA(usage, "");
4580     RegCloseKey(usage);
4581     RegDeleteKeyA(hkey, "");
4582     RegCloseKey(hkey);
4583
4584     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4586
4587     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4588
4589     RegDeleteKeyA(hkey, "");
4590     RegCloseKey(hkey);
4591
4592     /* RegisterProduct, machine */
4593     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
4594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4595     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4596     ok(delete_pf("msitest", FALSE), "File not installed\n");
4597
4598     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
4599     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4600
4601     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4603
4604     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4605     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4606     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4607     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4608     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4609     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4610     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4611     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4612     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4613     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4614     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4615     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4616     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4617     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4618     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4619     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4620     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4621     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4622     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4623     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4624     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4625     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4626     todo_wine
4627     {
4628         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4629     }
4630
4631     RegDeleteKeyA(hkey, "");
4632     RegCloseKey(hkey);
4633
4634     sprintf(keypath, userdata, "S-1-5-18");
4635     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4637
4638     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4640
4641     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4642     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4643     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4644     CHECK_DEL_REG_STR(props, "InstallDate", date);
4645     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4646     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4647     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4648     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4649     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4650     CHECK_DEL_REG_STR(props, "Comments", NULL);
4651     CHECK_DEL_REG_STR(props, "Contact", NULL);
4652     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4653     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4654     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4655     CHECK_DEL_REG_STR(props, "Readme", NULL);
4656     CHECK_DEL_REG_STR(props, "Size", NULL);
4657     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4658     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4659     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4660     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4661     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4662     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4663     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4664     todo_wine
4665     {
4666         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4667     }
4668
4669     RegDeleteKeyA(props, "");
4670     RegCloseKey(props);
4671
4672     res = RegOpenKeyA(hkey, "Usage", &usage);
4673     todo_wine
4674     {
4675         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4676     }
4677
4678     RegDeleteKeyA(usage, "");
4679     RegCloseKey(usage);
4680     RegDeleteKeyA(hkey, "");
4681     RegCloseKey(hkey);
4682
4683     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4685
4686     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4687
4688     RegDeleteKeyA(hkey, "");
4689     RegCloseKey(hkey);
4690
4691     DeleteFile(msifile);
4692     DeleteFile("msitest\\maximus");
4693     RemoveDirectory("msitest");
4694     HeapFree(GetProcessHeap(), 0, usersid);
4695 }
4696
4697 static void test_publish_publishproduct(void)
4698 {
4699     UINT r;
4700     LONG res;
4701     LPSTR usersid;
4702     HKEY sourcelist, net, props;
4703     HKEY hkey, patches, media;
4704     CHAR keypath[MAX_PATH];
4705     CHAR temp[MAX_PATH];
4706     CHAR path[MAX_PATH];
4707     BOOL old_installer = FALSE;
4708
4709     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4710                                    "\\Installer\\UserData\\%s\\Products"
4711                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4712     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
4713                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4714     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4715                                      "\\51AAE0C44620A5E4788506E91F249BD2";
4716     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4717                                   "\\Installer\\Products"
4718                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4719     static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4720     static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4721
4722     if (!get_user_sid(&usersid))
4723         return;
4724
4725     GetTempPath(MAX_PATH, temp);
4726
4727     CreateDirectoryA("msitest", NULL);
4728     create_file("msitest\\maximus", 500);
4729
4730     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4731
4732     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4733
4734     /* PublishProduct, current user */
4735     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4737     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4738     ok(delete_pf("msitest", FALSE), "File not installed\n");
4739
4740     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4741     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4742
4743     sprintf(keypath, prodpath, usersid);
4744     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4745     if (res == ERROR_FILE_NOT_FOUND)
4746     {
4747         res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4748         if (res == ERROR_SUCCESS)
4749         {
4750             win_skip("Windows Installer < 3.0 detected\n");
4751             RegCloseKey(hkey);
4752             old_installer = TRUE;
4753             goto currentuser;
4754         }
4755         else
4756         {
4757             win_skip("Install failed, no need to continue\n");
4758             return;
4759         }
4760     }
4761     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4762
4763     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4764     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4765
4766     res = RegOpenKeyA(hkey, "Patches", &patches);
4767     todo_wine
4768     {
4769         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4770
4771         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4772     }
4773
4774     RegDeleteKeyA(patches, "");
4775     RegCloseKey(patches);
4776     RegDeleteKeyA(hkey, "");
4777     RegCloseKey(hkey);
4778
4779 currentuser:
4780     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4782
4783     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4784     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4785     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4786     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4787     if (!old_installer)
4788         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4789     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
4790     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4791     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4792     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4793
4794     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
4795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4796
4797     lstrcpyA(path, "n;1;");
4798     lstrcatA(path, temp);
4799     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
4800     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
4801
4802     res = RegOpenKeyA(sourcelist, "Net", &net);
4803     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4804
4805     CHECK_DEL_REG_STR(net, "1", temp);
4806
4807     RegDeleteKeyA(net, "");
4808     RegCloseKey(net);
4809
4810     res = RegOpenKeyA(sourcelist, "Media", &media);
4811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4812
4813     CHECK_DEL_REG_STR(media, "1", "DISK1;");
4814
4815     RegDeleteKeyA(media, "");
4816     RegCloseKey(media);
4817     RegDeleteKeyA(sourcelist, "");
4818     RegCloseKey(sourcelist);
4819     RegDeleteKeyA(hkey, "");
4820     RegCloseKey(hkey);
4821
4822     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
4823     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4824
4825     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4826
4827     RegDeleteKeyA(hkey, "");
4828     RegCloseKey(hkey);
4829
4830     /* PublishProduct, machine */
4831     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
4832     if (old_installer)
4833         goto machprod;
4834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4835     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4836     ok(delete_pf("msitest", FALSE), "File not installed\n");
4837
4838     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4839     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4840
4841     sprintf(keypath, prodpath, "S-1-5-18");
4842     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4844
4845     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4846     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4847
4848     res = RegOpenKeyA(hkey, "Patches", &patches);
4849     todo_wine
4850     {
4851         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4852
4853         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4854     }
4855
4856     RegDeleteKeyA(patches, "");
4857     RegCloseKey(patches);
4858     RegDeleteKeyA(hkey, "");
4859     RegCloseKey(hkey);
4860
4861 machprod:
4862     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
4863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4864
4865     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4866     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4867     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4868     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4869     if (!old_installer)
4870         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4871     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
4872     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4873     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4874     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4875
4876     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
4877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4878
4879     lstrcpyA(path, "n;1;");
4880     lstrcatA(path, temp);
4881     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
4882     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
4883
4884     res = RegOpenKeyA(sourcelist, "Net", &net);
4885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4886
4887     CHECK_DEL_REG_STR(net, "1", temp);
4888
4889     RegDeleteKeyA(net, "");
4890     RegCloseKey(net);
4891
4892     res = RegOpenKeyA(sourcelist, "Media", &media);
4893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4894
4895     CHECK_DEL_REG_STR(media, "1", "DISK1;");
4896
4897     RegDeleteKeyA(media, "");
4898     RegCloseKey(media);
4899     RegDeleteKeyA(sourcelist, "");
4900     RegCloseKey(sourcelist);
4901     RegDeleteKeyA(hkey, "");
4902     RegCloseKey(hkey);
4903
4904     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
4905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4906
4907     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4908
4909     RegDeleteKeyA(hkey, "");
4910     RegCloseKey(hkey);
4911
4912     DeleteFile(msifile);
4913     DeleteFile("msitest\\maximus");
4914     RemoveDirectory("msitest");
4915     HeapFree(GetProcessHeap(), 0, usersid);
4916 }
4917
4918 static void test_publish_publishfeatures(void)
4919 {
4920     UINT r;
4921     LONG res;
4922     HKEY hkey;
4923     LPSTR usersid;
4924     CHAR keypath[MAX_PATH];
4925
4926     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
4927                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4928     static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4929                                  "\\Installer\\UserData\\%s\\Products"
4930                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
4931     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4932                                   "\\Installer\\Features";
4933     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
4934                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4935
4936     if (!get_user_sid(&usersid))
4937         return;
4938
4939     CreateDirectoryA("msitest", NULL);
4940     create_file("msitest\\maximus", 500);
4941
4942     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4943
4944     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4945
4946     /* PublishFeatures, current user */
4947     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4949     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4950     ok(delete_pf("msitest", FALSE), "File not installed\n");
4951
4952     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
4953     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4954
4955     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
4956     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4957
4958     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
4959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4960
4961     CHECK_REG_STR(hkey, "feature", "");
4962     CHECK_REG_STR(hkey, "montecristo", "");
4963
4964     RegDeleteValueA(hkey, "feature");
4965     RegDeleteValueA(hkey, "montecristo");
4966     RegDeleteKeyA(hkey, "");
4967     RegCloseKey(hkey);
4968
4969     sprintf(keypath, udpath, usersid);
4970     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4972
4973     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
4974     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
4975
4976     RegDeleteValueA(hkey, "feature");
4977     RegDeleteValueA(hkey, "montecristo");
4978     RegDeleteKeyA(hkey, "");
4979     RegCloseKey(hkey);
4980
4981     /* PublishFeatures, machine */
4982     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
4983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4984     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4985     ok(delete_pf("msitest", FALSE), "File not installed\n");
4986
4987     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
4988     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4989
4990     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
4991     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4992
4993     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
4994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4995
4996     CHECK_REG_STR(hkey, "feature", "");
4997     CHECK_REG_STR(hkey, "montecristo", "");
4998
4999     RegDeleteValueA(hkey, "feature");
5000     RegDeleteValueA(hkey, "montecristo");
5001     RegDeleteKeyA(hkey, "");
5002     RegCloseKey(hkey);
5003
5004     sprintf(keypath, udpath, "S-1-5-18");
5005     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
5006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5007
5008     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
5009     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
5010
5011     RegDeleteValueA(hkey, "feature");
5012     RegDeleteValueA(hkey, "montecristo");
5013     RegDeleteKeyA(hkey, "");
5014     RegCloseKey(hkey);
5015
5016     DeleteFile(msifile);
5017     DeleteFile("msitest\\maximus");
5018     RemoveDirectory("msitest");
5019     HeapFree(GetProcessHeap(), 0, usersid);
5020 }
5021
5022 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
5023 {
5024     DWORD len = 0;
5025     LPSTR val;
5026     LONG r;
5027
5028     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
5029     if (r != ERROR_SUCCESS)
5030         return NULL;
5031
5032     len += sizeof (WCHAR);
5033     val = HeapAlloc(GetProcessHeap(), 0, len);
5034     if (!val) return NULL;
5035     val[0] = 0;
5036     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
5037     return val;
5038 }
5039
5040 static void get_owner_company(LPSTR *owner, LPSTR *company)
5041 {
5042     LONG res;
5043     HKEY hkey;
5044
5045     *owner = *company = NULL;
5046
5047     res = RegOpenKeyA(HKEY_CURRENT_USER,
5048                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
5049     if (res == ERROR_SUCCESS)
5050     {
5051         *owner = reg_get_val_str(hkey, "DefName");
5052         *company = reg_get_val_str(hkey, "DefCompany");
5053         RegCloseKey(hkey);
5054     }
5055
5056     if (!*owner || !*company)
5057     {
5058         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
5059                           "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
5060         if (res == ERROR_SUCCESS)
5061         {
5062             *owner = reg_get_val_str(hkey, "RegisteredOwner");
5063             *company = reg_get_val_str(hkey, "RegisteredOrganization");
5064             RegCloseKey(hkey);
5065         }
5066     }
5067
5068     if (!*owner || !*company)
5069     {
5070         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
5071                           "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
5072         if (res == ERROR_SUCCESS)
5073         {
5074             *owner = reg_get_val_str(hkey, "RegisteredOwner");
5075             *company = reg_get_val_str(hkey, "RegisteredOrganization");
5076             RegCloseKey(hkey);
5077         }
5078     }
5079 }
5080
5081 static void test_publish_registeruser(void)
5082 {
5083     UINT r;
5084     LONG res;
5085     HKEY props;
5086     LPSTR usersid;
5087     LPSTR owner, company;
5088     CHAR keypath[MAX_PATH];
5089
5090     static const CHAR keyfmt[] =
5091         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
5092         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
5093
5094     if (!get_user_sid(&usersid))
5095         return;
5096
5097     get_owner_company(&owner, &company);
5098
5099     CreateDirectoryA("msitest", NULL);
5100     create_file("msitest\\maximus", 500);
5101
5102     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5103
5104     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5105
5106     /* RegisterUser, per-user */
5107     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
5108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5109     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5110     ok(delete_pf("msitest", FALSE), "File not installed\n");
5111
5112     sprintf(keypath, keyfmt, usersid);
5113
5114     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5115     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5116
5117     CHECK_REG_STR(props, "ProductID", "none");
5118     CHECK_REG_STR(props, "RegCompany", company);
5119     CHECK_REG_STR(props, "RegOwner", owner);
5120
5121     RegDeleteValueA(props, "ProductID");
5122     RegDeleteValueA(props, "RegCompany");
5123     RegDeleteValueA(props, "RegOwner");
5124     RegDeleteKeyA(props, "");
5125     RegCloseKey(props);
5126
5127     /* RegisterUser, machine */
5128     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
5129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5130     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5131     ok(delete_pf("msitest", FALSE), "File not installed\n");
5132
5133     sprintf(keypath, keyfmt, "S-1-5-18");
5134
5135     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5137
5138     CHECK_REG_STR(props, "ProductID", "none");
5139     CHECK_REG_STR(props, "RegCompany", company);
5140     CHECK_REG_STR(props, "RegOwner", owner);
5141
5142     RegDeleteValueA(props, "ProductID");
5143     RegDeleteValueA(props, "RegCompany");
5144     RegDeleteValueA(props, "RegOwner");
5145     RegDeleteKeyA(props, "");
5146     RegCloseKey(props);
5147
5148     HeapFree(GetProcessHeap(), 0, company);
5149     HeapFree(GetProcessHeap(), 0, owner);
5150
5151     DeleteFile(msifile);
5152     DeleteFile("msitest\\maximus");
5153     RemoveDirectory("msitest");
5154     LocalFree(usersid);
5155 }
5156
5157 static void test_publish_processcomponents(void)
5158 {
5159     UINT r;
5160     LONG res;
5161     DWORD size;
5162     HKEY comp, hkey;
5163     LPSTR usersid;
5164     CHAR val[MAX_PATH];
5165     CHAR keypath[MAX_PATH];
5166     CHAR program_files_maximus[MAX_PATH];
5167
5168     static const CHAR keyfmt[] =
5169         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
5170         "UserData\\%s\\Components\\%s";
5171     static const CHAR compkey[] =
5172         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
5173
5174     if (!get_user_sid(&usersid))
5175         return;
5176
5177     CreateDirectoryA("msitest", NULL);
5178     create_file("msitest\\maximus", 500);
5179
5180     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
5181
5182     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5183
5184     /* ProcessComponents, per-user */
5185     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5186     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5187     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5188     ok(delete_pf("msitest", FALSE), "File not installed\n");
5189
5190     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
5191
5192     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5194
5195     size = MAX_PATH;
5196     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5197                            NULL, NULL, (LPBYTE)val, &size);
5198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5199
5200     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
5201     lstrcatA(program_files_maximus,"\\msitest\\maximus");
5202
5203     ok(!lstrcmpiA(val, program_files_maximus),
5204        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5205
5206     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5207     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5208
5209     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5210     RegDeleteKeyA(comp, "");
5211     RegCloseKey(comp);
5212
5213     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
5214
5215     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5217
5218     size = MAX_PATH;
5219     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5220                            NULL, NULL, (LPBYTE)val, &size);
5221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5222     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5223        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5224
5225     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5226     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5227
5228     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5229     RegDeleteKeyA(comp, "");
5230     RegCloseKey(comp);
5231
5232     /* ProcessComponents, machine */
5233     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
5234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5235     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5236     ok(delete_pf("msitest", FALSE), "File not installed\n");
5237
5238     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
5239
5240     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5242
5243     size = MAX_PATH;
5244     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5245                            NULL, NULL, (LPBYTE)val, &size);
5246     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5247     ok(!lstrcmpiA(val, program_files_maximus),
5248        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5249
5250     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5251     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5252
5253     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5254     RegDeleteKeyA(comp, "");
5255     RegCloseKey(comp);
5256
5257     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
5258
5259     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5260     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5261
5262     size = MAX_PATH;
5263     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5264                            NULL, NULL, (LPBYTE)val, &size);
5265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5266     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5267        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5268
5269     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5270     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5271
5272     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5273     RegDeleteKeyA(comp, "");
5274     RegCloseKey(comp);
5275
5276     DeleteFile(msifile);
5277     DeleteFile("msitest\\maximus");
5278     RemoveDirectory("msitest");
5279     LocalFree(usersid);
5280 }
5281
5282 static void test_publish(void)
5283 {
5284     UINT r;
5285     LONG res;
5286     HKEY uninstall, prodkey;
5287     INSTALLSTATE state;
5288     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5289     char date[MAX_PATH];
5290     char temp[MAX_PATH];
5291
5292     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
5293
5294     if (!pMsiQueryComponentStateA)
5295     {
5296         win_skip("MsiQueryComponentStateA is not available\n");
5297         return;
5298     }
5299
5300     get_date_str(date);
5301     GetTempPath(MAX_PATH, temp);
5302
5303     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
5304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5305
5306     CreateDirectoryA("msitest", NULL);
5307     create_file("msitest\\maximus", 500);
5308
5309     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5310
5311     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5312
5313     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5314     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5315
5316     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5317     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5318
5319     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5320     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5321
5322     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5323                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5324     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5325     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5326
5327     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5328     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5329
5330     /* nothing published */
5331     r = MsiInstallProductA(msifile, NULL);
5332     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5333     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5334     ok(pf_exists("msitest"), "File not installed\n");
5335
5336     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5337     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5338
5339     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5340     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5341
5342     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5343     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5344
5345     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5346                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5347     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5348     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5349
5350     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5351     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5352
5353     /* PublishProduct and RegisterProduct */
5354     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
5355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5356     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5357     ok(pf_exists("msitest"), "File not installed\n");
5358
5359     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5360     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5361
5362     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5363     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5364
5365     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5366     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5367
5368     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5369                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5370     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
5371     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5372
5373     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5375
5376     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5377     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5378     CHECK_REG_STR(prodkey, "InstallDate", date);
5379     CHECK_REG_STR(prodkey, "InstallSource", temp);
5380     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5381     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5382     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5383     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5384     CHECK_REG_STR(prodkey, "Comments", NULL);
5385     CHECK_REG_STR(prodkey, "Contact", NULL);
5386     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5387     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5388     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5389     CHECK_REG_STR(prodkey, "Readme", NULL);
5390     CHECK_REG_STR(prodkey, "Size", NULL);
5391     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5392     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5393     CHECK_REG_DWORD(prodkey, "Language", 1033);
5394     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5395     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5396     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5397     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5398     todo_wine
5399     {
5400         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5401     }
5402
5403     RegCloseKey(prodkey);
5404
5405     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5407     ok(pf_exists("msitest\\maximus"), "File deleted\n");
5408     ok(pf_exists("msitest"), "File deleted\n");
5409
5410     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5411     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5412
5413     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5414     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5415
5416     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5417     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5418
5419     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5420                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5421     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5422     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5423
5424     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5425     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5426
5427     /* complete install */
5428     r = MsiInstallProductA(msifile, "FULL=1");
5429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5430     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5431     ok(pf_exists("msitest"), "File not installed\n");
5432
5433     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5434     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5435
5436     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5437     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5438
5439     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5440     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5441
5442     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5443                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5444     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5445     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5446
5447     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5449
5450     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5451     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5452     CHECK_REG_STR(prodkey, "InstallDate", date);
5453     CHECK_REG_STR(prodkey, "InstallSource", temp);
5454     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5455     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5456     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5457     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5458     CHECK_REG_STR(prodkey, "Comments", NULL);
5459     CHECK_REG_STR(prodkey, "Contact", NULL);
5460     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5461     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5462     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5463     CHECK_REG_STR(prodkey, "Readme", NULL);
5464     CHECK_REG_STR(prodkey, "Size", NULL);
5465     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5466     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5467     CHECK_REG_DWORD(prodkey, "Language", 1033);
5468     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5469     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5470     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5471     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5472     todo_wine
5473     {
5474         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5475     }
5476
5477     RegCloseKey(prodkey);
5478
5479     /* no UnpublishFeatures */
5480     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5482     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5483     ok(!pf_exists("msitest"), "Directory not deleted\n");
5484
5485     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5486     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5487
5488     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5489     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5490
5491     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5492     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5493
5494     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5495                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5496     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5497     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5498
5499     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5500     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5501
5502     /* complete install */
5503     r = MsiInstallProductA(msifile, "FULL=1");
5504     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5505     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5506     ok(pf_exists("msitest"), "File not installed\n");
5507
5508     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5509     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5510
5511     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5512     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5513
5514     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5515     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5516
5517     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5518                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5519     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5520     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5521
5522     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5524
5525     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5526     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5527     CHECK_REG_STR(prodkey, "InstallDate", date);
5528     CHECK_REG_STR(prodkey, "InstallSource", temp);
5529     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5530     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5531     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5532     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5533     CHECK_REG_STR(prodkey, "Comments", NULL);
5534     CHECK_REG_STR(prodkey, "Contact", NULL);
5535     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5536     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5537     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5538     CHECK_REG_STR(prodkey, "Readme", NULL);
5539     CHECK_REG_STR(prodkey, "Size", NULL);
5540     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5541     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5542     CHECK_REG_DWORD(prodkey, "Language", 1033);
5543     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5544     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5545     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5546     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5547     todo_wine
5548     {
5549         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5550     }
5551
5552     RegCloseKey(prodkey);
5553
5554     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
5555     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
5556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5557     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
5558     todo_wine ok(pf_exists("msitest"), "Directory deleted\n");
5559
5560     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5561     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5562
5563     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5564     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5565
5566     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5567     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5568
5569     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5570                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5572     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5573
5574     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5576
5577     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5578     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5579     CHECK_REG_STR(prodkey, "InstallDate", date);
5580     CHECK_REG_STR(prodkey, "InstallSource", temp);
5581     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5582     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5583     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5584     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5585     CHECK_REG_STR(prodkey, "Comments", NULL);
5586     CHECK_REG_STR(prodkey, "Contact", NULL);
5587     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5588     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5589     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5590     CHECK_REG_STR(prodkey, "Readme", NULL);
5591     CHECK_REG_STR(prodkey, "Size", NULL);
5592     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5593     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5594     CHECK_REG_DWORD(prodkey, "Language", 1033);
5595     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5596     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5597     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5598     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5599     todo_wine
5600     {
5601         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5602     }
5603
5604     RegCloseKey(prodkey);
5605
5606     /* complete install */
5607     r = MsiInstallProductA(msifile, "FULL=1");
5608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5609     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5610     ok(pf_exists("msitest"), "File not installed\n");
5611
5612     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5613     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5614
5615     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5616     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5617
5618     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5619     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5620
5621     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5622                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5623     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5624     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5625
5626     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5628
5629     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5630     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5631     CHECK_REG_STR(prodkey, "InstallDate", date);
5632     CHECK_REG_STR(prodkey, "InstallSource", temp);
5633     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5634     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5635     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5636     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5637     CHECK_REG_STR(prodkey, "Comments", NULL);
5638     CHECK_REG_STR(prodkey, "Contact", NULL);
5639     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5640     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5641     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5642     CHECK_REG_STR(prodkey, "Readme", NULL);
5643     CHECK_REG_STR(prodkey, "Size", NULL);
5644     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5645     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5646     CHECK_REG_DWORD(prodkey, "Language", 1033);
5647     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5648     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5649     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5650     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5651     todo_wine
5652     {
5653         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
5654     }
5655
5656     RegCloseKey(prodkey);
5657
5658     /* UnpublishFeatures, both features removed */
5659     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
5660     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5661     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5662     ok(!pf_exists("msitest"), "Directory not deleted\n");
5663
5664     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5665     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5666
5667     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5668     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5669
5670     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5671     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5672
5673     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5674                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5675     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5676     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5677
5678     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5679     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5680
5681     /* complete install */
5682     r = MsiInstallProductA(msifile, "FULL=1");
5683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5684     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5685     ok(pf_exists("msitest"), "File not installed\n");
5686
5687     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5688     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5689
5690     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5691     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5692
5693     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5694     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5695
5696     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5697                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5699     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5700
5701     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5703
5704     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5705     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5706     CHECK_REG_STR(prodkey, "InstallDate", date);
5707     CHECK_REG_STR(prodkey, "InstallSource", temp);
5708     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5709     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5710     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5711     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5712     CHECK_REG_STR(prodkey, "Comments", NULL);
5713     CHECK_REG_STR(prodkey, "Contact", NULL);
5714     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5715     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5716     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5717     CHECK_REG_STR(prodkey, "Readme", NULL);
5718     CHECK_REG_STR(prodkey, "Size", NULL);
5719     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5720     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5721     CHECK_REG_DWORD(prodkey, "Language", 1033);
5722     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5723     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5724     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5725     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5726     todo_wine
5727     {
5728         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5729     }
5730
5731     RegCloseKey(prodkey);
5732
5733     /* complete uninstall */
5734     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5735     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5736     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5737     ok(!pf_exists("msitest"), "Directory not deleted\n");
5738
5739     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5740     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5741
5742     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5743     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5744
5745     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5746     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5747
5748     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5749                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5750     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5751     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5752
5753     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5754     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5755
5756     /* make sure 'Program Files\msitest' is removed */
5757     delete_pfmsitest_files();
5758
5759     RegCloseKey(uninstall);
5760     DeleteFile(msifile);
5761     DeleteFile("msitest\\maximus");
5762     RemoveDirectory("msitest");
5763 }
5764
5765 static void test_publishsourcelist(void)
5766 {
5767     UINT r;
5768     DWORD size;
5769     CHAR value[MAX_PATH];
5770     CHAR path[MAX_PATH];
5771     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5772
5773     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
5774     {
5775         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
5776         return;
5777     }
5778
5779     CreateDirectoryA("msitest", NULL);
5780     create_file("msitest\\maximus", 500);
5781
5782     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5783
5784     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5785
5786     r = MsiInstallProductA(msifile, NULL);
5787     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5788     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5789     ok(pf_exists("msitest"), "File not installed\n");
5790
5791     /* nothing published */
5792     size = MAX_PATH;
5793     lstrcpyA(value, "aaa");
5794     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5795                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5796     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5797     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5798     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5799
5800     size = MAX_PATH;
5801     lstrcpyA(value, "aaa");
5802     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5803                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5804     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5805     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5806     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5807
5808     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
5809     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5810     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5811     ok(pf_exists("msitest"), "File not installed\n");
5812
5813     /* after RegisterProduct */
5814     size = MAX_PATH;
5815     lstrcpyA(value, "aaa");
5816     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5817                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5818     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5819     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5820     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5821
5822     size = MAX_PATH;
5823     lstrcpyA(value, "aaa");
5824     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5825                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5826     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5827     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5828     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5829
5830     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5832     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5833     ok(pf_exists("msitest"), "File not installed\n");
5834
5835     /* after ProcessComponents */
5836     size = MAX_PATH;
5837     lstrcpyA(value, "aaa");
5838     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5839                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5840     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5841     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5842     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5843
5844     size = MAX_PATH;
5845     lstrcpyA(value, "aaa");
5846     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5847                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5848     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5849     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5850     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5851
5852     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
5853     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5854     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5855     ok(pf_exists("msitest"), "File not installed\n");
5856
5857     /* after PublishFeatures */
5858     size = MAX_PATH;
5859     lstrcpyA(value, "aaa");
5860     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5861                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5862     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5863     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5864     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5865
5866     size = MAX_PATH;
5867     lstrcpyA(value, "aaa");
5868     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5869                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5870     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5871     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
5872     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
5873
5874     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
5875     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5876     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5877     ok(pf_exists("msitest"), "File not installed\n");
5878
5879     /* after PublishProduct */
5880     size = MAX_PATH;
5881     lstrcpyA(value, "aaa");
5882     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5883                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
5884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5885     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
5886     ok(size == 11, "Expected 11, got %d\n", size);
5887
5888     size = MAX_PATH;
5889     lstrcpyA(value, "aaa");
5890     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5891                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
5892     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5893     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5894     ok(size == 0, "Expected 0, got %d\n", size);
5895
5896     size = MAX_PATH;
5897     lstrcpyA(value, "aaa");
5898     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5899                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
5900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5901     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
5902     ok(size == 0, "Expected 0, got %d\n", size);
5903
5904     lstrcpyA(path, CURR_DIR);
5905     lstrcatA(path, "\\");
5906
5907     size = MAX_PATH;
5908     lstrcpyA(value, "aaa");
5909     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5910                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
5911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5912     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5913     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5914
5915     size = MAX_PATH;
5916     lstrcpyA(value, "aaa");
5917     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5918                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
5919     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5920     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
5921     ok(size == 1, "Expected 1, got %d\n", size);
5922
5923     size = MAX_PATH;
5924     lstrcpyA(value, "aaa");
5925     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5926                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
5927     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5928     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5929     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5930
5931     size = MAX_PATH;
5932     lstrcpyA(value, "aaa");
5933     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5934                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
5935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5936     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
5937     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
5938
5939     size = MAX_PATH;
5940     lstrcpyA(value, "aaa");
5941     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5942                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
5943     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
5944     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
5945     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
5946
5947     /* complete uninstall */
5948     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5950     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5951     ok(!pf_exists("msitest"), "Directory not deleted\n");
5952
5953     /* make sure 'Program Files\msitest' is removed */
5954     delete_pfmsitest_files();
5955
5956     DeleteFile(msifile);
5957     DeleteFile("msitest\\maximus");
5958     RemoveDirectory("msitest");
5959 }
5960
5961 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
5962 {
5963     MSIHANDLE hview = 0;
5964     UINT r;
5965
5966     r = MsiDatabaseOpenView(hdb, query, &hview);
5967     if(r != ERROR_SUCCESS)
5968         return r;
5969
5970     r = MsiViewExecute(hview, hrec);
5971     if(r == ERROR_SUCCESS)
5972         r = MsiViewClose(hview);
5973     MsiCloseHandle(hview);
5974     return r;
5975 }
5976
5977 static void set_transform_summary_info(void)
5978 {
5979     UINT r;
5980     MSIHANDLE suminfo = 0;
5981
5982     /* build summary info */
5983     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
5984     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
5985
5986     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
5987     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5988
5989     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
5990                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5991                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
5992                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
5993     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
5994
5995     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
5996     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
5997
5998     r = MsiSummaryInfoPersist(suminfo);
5999     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
6000
6001     r = MsiCloseHandle(suminfo);
6002     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
6003 }
6004
6005 static void generate_transform(void)
6006 {
6007     MSIHANDLE hdb1, hdb2;
6008     LPCSTR query;
6009     UINT r;
6010
6011     /* start with two identical databases */
6012     CopyFile(msifile, msifile2, FALSE);
6013
6014     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
6015     ok(r == ERROR_SUCCESS , "Failed to create database\n");
6016
6017     r = MsiDatabaseCommit(hdb1);
6018     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6019
6020     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
6021     ok(r == ERROR_SUCCESS , "Failed to create database\n");
6022
6023     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
6024     r = run_query(hdb1, 0, query);
6025     ok(r == ERROR_SUCCESS, "failed to add property\n");
6026
6027     /* database needs to be committed */
6028     MsiDatabaseCommit(hdb1);
6029
6030     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
6031     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
6032
6033 #if 0  /* not implemented in wine yet */
6034     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
6035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6036 #endif
6037
6038     MsiCloseHandle(hdb1);
6039     MsiCloseHandle(hdb2);
6040 }
6041
6042 /* data for generating a transform */
6043
6044 /* tables transform names - encoded as they would be in an msi database file */
6045 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
6046 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
6047 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
6048
6049 /* data in each table */
6050 static const char data1[] = /* _StringData */
6051     "propval";  /* all the strings squashed together */
6052
6053 static const WCHAR data2[] = { /* _StringPool */
6054 /*  len, refs */
6055     0,   0,    /* string 0 ''     */
6056     4,   1,    /* string 1 'prop' */
6057     3,   1,    /* string 2 'val'  */
6058 };
6059
6060 static const WCHAR data3[] = { /* Property */
6061     0x0201, 0x0001, 0x0002,
6062 };
6063
6064 static const struct {
6065     LPCWSTR name;
6066     const void *data;
6067     DWORD size;
6068 } table_transform_data[] =
6069 {
6070     { name1, data1, sizeof data1 - 1 },
6071     { name2, data2, sizeof data2 },
6072     { name3, data3, sizeof data3 },
6073 };
6074
6075 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
6076
6077 static void generate_transform_manual(void)
6078 {
6079     IStorage *stg = NULL;
6080     IStream *stm;
6081     WCHAR name[0x20];
6082     HRESULT r;
6083     DWORD i, count;
6084     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
6085
6086     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
6087
6088     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
6089
6090     r = StgCreateDocfile(name, mode, 0, &stg);
6091     ok(r == S_OK, "failed to create storage\n");
6092     if (!stg)
6093         return;
6094
6095     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
6096     ok(r == S_OK, "failed to set storage type\n");
6097
6098     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
6099     {
6100         r = IStorage_CreateStream(stg, table_transform_data[i].name,
6101                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
6102         if (FAILED(r))
6103         {
6104             ok(0, "failed to create stream %08x\n", r);
6105             continue;
6106         }
6107
6108         r = IStream_Write(stm, table_transform_data[i].data,
6109                           table_transform_data[i].size, &count);
6110         if (FAILED(r) || count != table_transform_data[i].size)
6111             ok(0, "failed to write stream\n");
6112         IStream_Release(stm);
6113     }
6114
6115     IStorage_Release(stg);
6116
6117     set_transform_summary_info();
6118 }
6119
6120 static void test_transformprop(void)
6121 {
6122     UINT r;
6123
6124     CreateDirectoryA("msitest", NULL);
6125     create_file("msitest\\augustus", 500);
6126
6127     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
6128
6129     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6130
6131     r = MsiInstallProductA(msifile, NULL);
6132     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6133     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6134     ok(!delete_pf("msitest", FALSE), "File installed\n");
6135
6136     if (0)
6137         generate_transform();
6138     else
6139         generate_transform_manual();
6140
6141     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
6142     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6143     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6144     ok(delete_pf("msitest", FALSE), "File not installed\n");
6145
6146     /* Delete the files in the temp (current) folder */
6147     DeleteFile(msifile);
6148     DeleteFile(msifile2);
6149     DeleteFile(mstfile);
6150     DeleteFile("msitest\\augustus");
6151     RemoveDirectory("msitest");
6152 }
6153
6154 static void test_currentworkingdir(void)
6155 {
6156     UINT r;
6157     CHAR drive[MAX_PATH], path[MAX_PATH];
6158     LPSTR ptr;
6159
6160     CreateDirectoryA("msitest", NULL);
6161     create_file("msitest\\augustus", 500);
6162
6163     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
6164
6165     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6166
6167     CreateDirectoryA("diffdir", NULL);
6168     SetCurrentDirectoryA("diffdir");
6169
6170     sprintf(path, "..\\%s", msifile);
6171     r = MsiInstallProductA(path, NULL);
6172     todo_wine
6173     {
6174         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
6175         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6176         ok(!delete_pf("msitest", FALSE), "File installed\n");
6177     }
6178
6179     sprintf(path, "%s\\%s", CURR_DIR, msifile);
6180     r = MsiInstallProductA(path, NULL);
6181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6182     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6183     ok(delete_pf("msitest", FALSE), "File not installed\n");
6184
6185     lstrcpyA(drive, CURR_DIR);
6186     drive[2] = '\\';
6187     drive[3] = '\0';
6188     SetCurrentDirectoryA(drive);
6189
6190     lstrcpy(path, CURR_DIR);
6191     if (path[lstrlenA(path) - 1] != '\\')
6192         lstrcatA(path, "\\");
6193     lstrcatA(path, msifile);
6194     ptr = strchr(path, ':');
6195     ptr +=2;
6196
6197     r = MsiInstallProductA(ptr, NULL);
6198     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6199     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6200     ok(delete_pf("msitest", FALSE), "File not installed\n");
6201
6202     SetCurrentDirectoryA(CURR_DIR);
6203
6204     DeleteFile(msifile);
6205     DeleteFile("msitest\\augustus");
6206     RemoveDirectory("msitest");
6207     RemoveDirectory("diffdir");
6208 }
6209
6210 static void set_admin_summary_info(const CHAR *name)
6211 {
6212     MSIHANDLE db, summary;
6213     UINT r;
6214
6215     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
6216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6217
6218     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6220
6221     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
6222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6223
6224     /* write the summary changes back to the stream */
6225     r = MsiSummaryInfoPersist(summary);
6226     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6227
6228     MsiCloseHandle(summary);
6229
6230     r = MsiDatabaseCommit(db);
6231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6232
6233     MsiCloseHandle(db);
6234 }
6235
6236 static void test_admin(void)
6237 {
6238     UINT r;
6239
6240     CreateDirectoryA("msitest", NULL);
6241     create_file("msitest\\augustus", 500);
6242
6243     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
6244     set_admin_summary_info(msifile);
6245
6246     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6247
6248     r = MsiInstallProductA(msifile, NULL);
6249     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6250     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6251     ok(!delete_pf("msitest", FALSE), "File installed\n");
6252     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
6253     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
6254
6255     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
6256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6257     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6258     ok(!delete_pf("msitest", FALSE), "File installed\n");
6259     todo_wine
6260     {
6261         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
6262         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
6263     }
6264
6265     DeleteFile(msifile);
6266     DeleteFile("msitest\\augustus");
6267     RemoveDirectory("msitest");
6268 }
6269
6270 static void set_admin_property_stream(LPCSTR file)
6271 {
6272     IStorage *stg;
6273     IStream *stm;
6274     WCHAR fileW[MAX_PATH];
6275     HRESULT hr;
6276     DWORD count;
6277     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
6278
6279     /* AdminProperties */
6280     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
6281     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
6282         'M','y','P','r','o','p','=','4','2',0};
6283
6284     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
6285
6286     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
6287     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6288     if (!stg)
6289         return;
6290
6291     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
6292     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6293
6294     hr = IStream_Write(stm, data, sizeof(data), &count);
6295     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6296
6297     IStream_Release(stm);
6298     IStorage_Release(stg);
6299 }
6300
6301 static void test_adminprops(void)
6302 {
6303     UINT r;
6304
6305     CreateDirectoryA("msitest", NULL);
6306     create_file("msitest\\augustus", 500);
6307
6308     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
6309     set_admin_summary_info(msifile);
6310     set_admin_property_stream(msifile);
6311
6312     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6313
6314     r = MsiInstallProductA(msifile, NULL);
6315     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6316     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6317     ok(delete_pf("msitest", FALSE), "File installed\n");
6318
6319     DeleteFile(msifile);
6320     DeleteFile("msitest\\augustus");
6321     RemoveDirectory("msitest");
6322 }
6323
6324 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
6325 {
6326     CHAR path[MAX_PATH];
6327
6328     lstrcpyA(path, PROG_FILES_DIR);
6329     lstrcatA(path, "\\");
6330     lstrcatA(path, file);
6331
6332     if (is_file)
6333         create_file_data(path, data, 500);
6334     else
6335         CreateDirectoryA(path, NULL);
6336 }
6337
6338 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
6339
6340 static void test_removefiles(void)
6341 {
6342     UINT r;
6343
6344     CreateDirectoryA("msitest", NULL);
6345     create_file("msitest\\hydrogen", 500);
6346     create_file("msitest\\helium", 500);
6347     create_file("msitest\\lithium", 500);
6348
6349     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
6350
6351     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6352
6353     r = MsiInstallProductA(msifile, NULL);
6354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6355     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6356     ok(!pf_exists("msitest\\helium"), "File installed\n");
6357     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6358     ok(pf_exists("msitest"), "File not installed\n");
6359
6360     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6361     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6362     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6363     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
6364     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6365     ok(delete_pf("msitest", FALSE), "File deleted\n");
6366
6367     create_pf("msitest", FALSE);
6368     create_pf("msitest\\hydrogen", TRUE);
6369     create_pf("msitest\\helium", TRUE);
6370     create_pf("msitest\\lithium", TRUE);
6371
6372     r = MsiInstallProductA(msifile, NULL);
6373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6374     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6375     ok(pf_exists("msitest\\helium"), "File not installed\n");
6376     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6377     ok(pf_exists("msitest"), "File not installed\n");
6378
6379     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6380     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6381     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6382     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
6383     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6384     ok(delete_pf("msitest", FALSE), "File deleted\n");
6385
6386     create_pf("msitest", FALSE);
6387     create_pf("msitest\\furlong", TRUE);
6388     create_pf("msitest\\firkin", TRUE);
6389     create_pf("msitest\\fortnight", TRUE);
6390     create_pf("msitest\\becquerel", TRUE);
6391     create_pf("msitest\\dioptre", TRUE);
6392     create_pf("msitest\\attoparsec", TRUE);
6393     create_pf("msitest\\storeys", TRUE);
6394     create_pf("msitest\\block", TRUE);
6395     create_pf("msitest\\siriometer", TRUE);
6396     create_pf("msitest\\cabout", FALSE);
6397     create_pf("msitest\\cabout\\blocker", TRUE);
6398
6399     r = MsiInstallProductA(msifile, NULL);
6400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6401     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6402     ok(!pf_exists("msitest\\helium"), "File installed\n");
6403     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6404     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
6405     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
6406     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
6407     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
6408     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
6409     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
6410     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
6411     ok(!pf_exists("msitest\\block"), "File not deleted\n");
6412     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
6413     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
6414     ok(pf_exists("msitest"), "File not installed\n");
6415
6416     create_pf("msitest\\furlong", TRUE);
6417     create_pf("msitest\\firkin", TRUE);
6418     create_pf("msitest\\fortnight", TRUE);
6419     create_pf("msitest\\storeys", TRUE);
6420     create_pf("msitest\\block", TRUE);
6421     create_pf("msitest\\siriometer", TRUE);
6422
6423     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6425     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
6426     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
6427     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6428     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
6429     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
6430     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
6431     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
6432     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
6433     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
6434     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
6435     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
6436     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
6437     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6438     ok(pf_exists("msitest"), "Directory deleted\n");
6439
6440     r = MsiInstallProductA(msifile, NULL);
6441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6442     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
6443     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
6444     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
6445     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6446     ok(pf_exists("msitest"), "Directory deleted\n");
6447
6448     delete_pf("msitest\\cabout\\blocker", TRUE);
6449
6450     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6452     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
6453     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
6454
6455     DeleteFile(msifile);
6456     DeleteFile("msitest\\hydrogen");
6457     DeleteFile("msitest\\helium");
6458     DeleteFile("msitest\\lithium");
6459     RemoveDirectory("msitest");
6460 }
6461
6462 static void test_movefiles(void)
6463 {
6464     UINT r;
6465     char props[MAX_PATH];
6466
6467     CreateDirectoryA("msitest", NULL);
6468     create_file("msitest\\augustus", 100);
6469     create_file("cameroon", 100);
6470     create_file("djibouti", 100);
6471     create_file("egypt", 100);
6472     create_file("finland", 100);
6473     create_file("gambai", 100);
6474     create_file("honduras", 100);
6475     create_file("msitest\\india", 100);
6476     create_file("japan", 100);
6477     create_file("kenya", 100);
6478     CreateDirectoryA("latvia", NULL);
6479     create_file("nauru", 100);
6480     create_file("peru", 100);
6481     create_file("apple", 100);
6482     create_file("application", 100);
6483     create_file("ape", 100);
6484     create_file("foo", 100);
6485     create_file("fao", 100);
6486     create_file("fbod", 100);
6487     create_file("budding", 100);
6488     create_file("buddy", 100);
6489     create_file("bud", 100);
6490     create_file("bar", 100);
6491     create_file("bur", 100);
6492     create_file("bird", 100);
6493
6494     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
6495
6496     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6497
6498     /* if the source or dest property is not a full path,
6499      * windows tries to access it as a network resource
6500      */
6501
6502     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
6503             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
6504             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
6505
6506     r = MsiInstallProductA(msifile, props);
6507     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6508     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6509     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
6510     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
6511     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
6512     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
6513     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
6514     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
6515     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
6516     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
6517     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
6518     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
6519     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
6520     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
6521     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
6522     /* either apple or application will be moved depending on directory order */
6523     if (!delete_pf("msitest\\apple", TRUE))
6524         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
6525     else
6526         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
6527     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
6528     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
6529     /* either fao or foo will be moved depending on directory order */
6530     if (delete_pf("msitest\\foo", TRUE))
6531         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
6532     else
6533         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
6534     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
6535     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
6536     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
6537     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
6538     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
6539     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
6540     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
6541     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
6542     ok(delete_pf("msitest", FALSE), "File not installed\n");
6543     ok(DeleteFileA("cameroon"), "File moved\n");
6544     ok(!DeleteFileA("djibouti"), "File not moved\n");
6545     ok(DeleteFileA("egypt"), "File moved\n");
6546     ok(DeleteFileA("finland"), "File moved\n");
6547     ok(DeleteFileA("gambai"), "File moved\n");
6548     ok(!DeleteFileA("honduras"), "File not moved\n");
6549     ok(DeleteFileA("msitest\\india"), "File moved\n");
6550     ok(DeleteFileA("japan"), "File moved\n");
6551     ok(!DeleteFileA("kenya"), "File not moved\n");
6552     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
6553     ok(!DeleteFileA("nauru"), "File not moved\n");
6554     ok(!DeleteFileA("peru"), "File not moved\n");
6555     ok(!DeleteFileA("apple"), "File not moved\n");
6556     ok(!DeleteFileA("application"), "File not moved\n");
6557     ok(DeleteFileA("ape"), "File moved\n");
6558     ok(!DeleteFileA("foo"), "File not moved\n");
6559     ok(!DeleteFileA("fao"), "File not moved\n");
6560     ok(DeleteFileA("fbod"), "File moved\n");
6561     ok(!DeleteFileA("budding"), "File not moved\n");
6562     ok(!DeleteFileA("buddy"), "File not moved\n");
6563     ok(DeleteFileA("bud"), "File moved\n");
6564     ok(!DeleteFileA("bar"), "File not moved\n");
6565     ok(!DeleteFileA("bur"), "File not moved\n");
6566     ok(DeleteFileA("bird"), "File moved\n");
6567
6568     DeleteFile("msitest\\augustus");
6569     RemoveDirectory("msitest");
6570     DeleteFile(msifile);
6571 }
6572
6573 static void test_missingcab(void)
6574 {
6575     UINT r;
6576
6577     CreateDirectoryA("msitest", NULL);
6578     create_file("msitest\\augustus", 500);
6579     create_file("maximus", 500);
6580
6581     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
6582
6583     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6584
6585     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6586
6587     create_pf("msitest", FALSE);
6588     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6589
6590     r = MsiInstallProductA(msifile, NULL);
6591     ok(r == ERROR_SUCCESS ||
6592        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
6593        "Expected ERROR_SUCCESS, got %u\n", r);
6594     if (r == ERROR_SUCCESS)
6595     {
6596       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6597       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6598     }
6599     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
6600     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
6601     ok(delete_pf("msitest", FALSE), "File not installed\n");
6602
6603     create_pf("msitest", FALSE);
6604     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6605     create_pf("msitest\\gaius", TRUE);
6606
6607     r = MsiInstallProductA(msifile, "GAIUS=1");
6608     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6609     todo_wine
6610     {
6611         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
6612         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6613     }
6614     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
6615     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
6616     ok(delete_pf("msitest", FALSE), "File not installed\n");
6617
6618     DeleteFile("msitest\\augustus");
6619     RemoveDirectory("msitest");
6620     DeleteFile("maximus");
6621     DeleteFile("test1.cab");
6622     DeleteFile(msifile);
6623 }
6624
6625 static void test_duplicatefiles(void)
6626 {
6627     UINT r;
6628
6629     CreateDirectoryA("msitest", NULL);
6630     create_file("msitest\\maximus", 500);
6631     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
6632
6633     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6634
6635     /* fails if the destination folder is not a valid property */
6636
6637     r = MsiInstallProductA(msifile, NULL);
6638     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6639     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6640     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
6641     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
6642     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
6643     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
6644     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
6645     ok(delete_pf("msitest", FALSE), "File not installed\n");
6646
6647     DeleteFile("msitest\\maximus");
6648     RemoveDirectory("msitest");
6649     DeleteFile(msifile);
6650 }
6651
6652 static void test_writeregistryvalues(void)
6653 {
6654     UINT r;
6655     LONG res;
6656     HKEY hkey;
6657     DWORD type, size;
6658     CHAR path[MAX_PATH];
6659
6660     CreateDirectoryA("msitest", NULL);
6661     create_file("msitest\\augustus", 500);
6662
6663     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
6664
6665     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6666
6667     r = MsiInstallProductA(msifile, NULL);
6668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6669     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6670     ok(delete_pf("msitest", FALSE), "File installed\n");
6671
6672     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
6673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6674
6675     size = MAX_PATH;
6676     type = REG_MULTI_SZ;
6677     memset(path, 'a', MAX_PATH);
6678     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
6679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6680     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
6681     ok(size == 15, "Expected 15, got %d\n", size);
6682     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
6683
6684     DeleteFile(msifile);
6685     DeleteFile("msitest\\augustus");
6686     RemoveDirectory("msitest");
6687
6688     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
6689     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
6690 }
6691
6692 static void test_sourcefolder(void)
6693 {
6694     UINT r;
6695
6696     CreateDirectoryA("msitest", NULL);
6697     create_file("augustus", 500);
6698
6699     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
6700
6701     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6702
6703     r = MsiInstallProductA(msifile, NULL);
6704     ok(r == ERROR_INSTALL_FAILURE,
6705        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6706     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6707     todo_wine
6708     {
6709         ok(!delete_pf("msitest", FALSE), "File installed\n");
6710     }
6711
6712     RemoveDirectoryA("msitest");
6713
6714     r = MsiInstallProductA(msifile, NULL);
6715     ok(r == ERROR_INSTALL_FAILURE,
6716        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6717     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6718     todo_wine
6719     {
6720         ok(!delete_pf("msitest", FALSE), "File installed\n");
6721     }
6722
6723     DeleteFile(msifile);
6724     DeleteFile("augustus");
6725 }
6726
6727 static void test_customaction51(void)
6728 {
6729     UINT r;
6730
6731     CreateDirectoryA("msitest", NULL);
6732     create_file("msitest\\augustus", 500);
6733
6734     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6735
6736     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6737
6738     r = MsiInstallProductA(msifile, NULL);
6739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6740     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6741     ok(delete_pf("msitest", FALSE), "File installed\n");
6742
6743     DeleteFile(msifile);
6744     DeleteFile("msitest\\augustus");
6745     RemoveDirectory("msitest");
6746 }
6747
6748 static void test_installstate(void)
6749 {
6750     UINT r;
6751
6752     CreateDirectoryA("msitest", NULL);
6753     create_file("msitest\\alpha", 500);
6754     create_file("msitest\\beta", 500);
6755     create_file("msitest\\gamma", 500);
6756     create_file("msitest\\theta", 500);
6757     create_file("msitest\\delta", 500);
6758     create_file("msitest\\epsilon", 500);
6759     create_file("msitest\\zeta", 500);
6760     create_file("msitest\\iota", 500);
6761     create_file("msitest\\eta", 500);
6762     create_file("msitest\\kappa", 500);
6763     create_file("msitest\\lambda", 500);
6764     create_file("msitest\\mu", 500);
6765
6766     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
6767
6768     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6769
6770     r = MsiInstallProductA(msifile, NULL);
6771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6772     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6773     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6774     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6775     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6776     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6777     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6778     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6779     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6780     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6781     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6782     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6783     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6784     ok(delete_pf("msitest", FALSE), "File not installed\n");
6785
6786     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
6787     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6788     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6789     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6790     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6791     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6792     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6793     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
6794     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6795     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6796     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
6797     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6798     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6799     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6800     ok(delete_pf("msitest", FALSE), "File not installed\n");
6801
6802     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
6803     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6804     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6805     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6806     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6807     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6808     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6809     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6810     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
6811     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6812     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6813     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6814     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6815     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6816     ok(delete_pf("msitest", FALSE), "File not installed\n");
6817
6818     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
6819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6820     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
6821     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6822     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
6823     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
6824     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6825     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6826     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6827     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6828     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6829     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6830     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6831     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6832     ok(!delete_pf("msitest", FALSE), "File installed\n");
6833
6834     DeleteFile(msifile);
6835     DeleteFile("msitest\\alpha");
6836     DeleteFile("msitest\\beta");
6837     DeleteFile("msitest\\gamma");
6838     DeleteFile("msitest\\theta");
6839     DeleteFile("msitest\\delta");
6840     DeleteFile("msitest\\epsilon");
6841     DeleteFile("msitest\\zeta");
6842     DeleteFile("msitest\\iota");
6843     DeleteFile("msitest\\eta");
6844     DeleteFile("msitest\\kappa");
6845     DeleteFile("msitest\\lambda");
6846     DeleteFile("msitest\\mu");
6847     RemoveDirectory("msitest");
6848 }
6849
6850 struct sourcepathmap
6851 {
6852     BOOL sost; /* shortone\shorttwo */
6853     BOOL solt; /* shortone\longtwo */
6854     BOOL lost; /* longone\shorttwo */
6855     BOOL lolt; /* longone\longtwo */
6856     BOOL soste; /* shortone\shorttwo source exists */
6857     BOOL solte; /* shortone\longtwo source exists */
6858     BOOL loste; /* longone\shorttwo source exists */
6859     BOOL lolte; /* longone\longtwo source exists */
6860     UINT err;
6861     DWORD size;
6862 } spmap[256] =
6863 {
6864     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6865     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6866     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6867     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6868     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6869     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6870     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6871     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6872     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6873     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6874     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6875     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6876     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6877     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6878     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6879     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6880     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6881     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6882     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6883     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6884     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6885     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6886     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6887     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6888     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6889     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6890     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6891     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6892     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6893     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6894     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6895     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6896     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6897     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6898     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6899     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6900     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6901     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6902     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6903     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6904     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6905     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6906     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6907     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6908     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6909     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6910     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6911     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6912     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6913     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6914     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6915     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6916     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6917     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6918     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6919     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6920     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6921     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6922     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6923     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6924     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6925     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6926     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6927     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6928     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6929     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6930     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6931     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6932     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6933     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6934     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6935     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6936     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6937     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6938     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6939     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6940     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6941     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6942     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6943     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6944     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6945     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6946     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6947     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6948     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6949     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6950     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6951     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6952     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6953     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6954     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6955     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6956     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6957     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6958     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6959     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6960     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6961     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6962     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6963     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6964     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6965     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6966     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6967     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6968     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6969     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6970     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6971     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6972     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6973     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6974     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6975     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6976     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6977     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6978     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6979     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6980     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6981     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6982     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6983     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6984     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6985     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6986     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6987     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6988     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
6989     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6990     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
6991     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6992     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
6993     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6994     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
6995     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
6996     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
6997     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
6998     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
6999     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7000     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7001     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7002     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7003     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7004     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7005     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7006     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7007     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7008     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7009     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7010     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7011     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7012     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7013     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7014     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7015     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7016     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7017     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7018     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7019     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7020     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7021     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7022     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7023     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7024     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7025     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7026     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7027     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7028     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7029     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7030     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7031     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7032     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7033     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7034     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7035     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7036     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7037     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7038     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7039     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7040     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7041     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7042     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7043     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7044     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7045     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7046     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7047     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7048     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7049     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7050     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7051     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7052     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7053     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7054     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7055     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7056     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7057     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7058     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7059     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7060     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7061     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7062     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7063     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7064     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7065     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7066     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7067     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7068     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7069     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7070     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7071     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7072     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7073     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7074     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7075     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7076     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7077     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7078     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7079     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7080     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7081     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7082     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7083     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7084     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7085     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7086     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7087     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7088     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7089     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7090     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7091     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7092     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7093     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7094     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7095     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7096     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7097     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7098     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7099     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7100     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7101     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7102     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7103     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7104     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7105     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7106     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7107     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7108     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7109     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7110     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7111     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7112     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7113     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7114     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7115     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7116     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7117     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7118     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7119     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7120 };
7121
7122 static DWORD get_pf_file_size(LPCSTR file)
7123 {
7124     CHAR path[MAX_PATH];
7125     HANDLE hfile;
7126     DWORD size;
7127
7128     lstrcpyA(path, PROG_FILES_DIR);
7129     lstrcatA(path, "\\");
7130     lstrcatA(path, file);
7131
7132     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7133     if (hfile == INVALID_HANDLE_VALUE)
7134         return 0;
7135
7136     size = GetFileSize(hfile, NULL);
7137     CloseHandle(hfile);
7138     return size;
7139 }
7140
7141 static void test_sourcepath(void)
7142 {
7143     UINT r, i;
7144
7145     if (!winetest_interactive)
7146     {
7147         skip("Run in interactive mode to run source path tests.\n");
7148         return;
7149     }
7150
7151     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
7152
7153     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7154
7155     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
7156     {
7157         if (spmap[i].sost)
7158         {
7159             CreateDirectoryA("shortone", NULL);
7160             CreateDirectoryA("shortone\\shorttwo", NULL);
7161         }
7162
7163         if (spmap[i].solt)
7164         {
7165             CreateDirectoryA("shortone", NULL);
7166             CreateDirectoryA("shortone\\longtwo", NULL);
7167         }
7168
7169         if (spmap[i].lost)
7170         {
7171             CreateDirectoryA("longone", NULL);
7172             CreateDirectoryA("longone\\shorttwo", NULL);
7173         }
7174
7175         if (spmap[i].lolt)
7176         {
7177             CreateDirectoryA("longone", NULL);
7178             CreateDirectoryA("longone\\longtwo", NULL);
7179         }
7180
7181         if (spmap[i].soste)
7182             create_file("shortone\\shorttwo\\augustus", 50);
7183         if (spmap[i].solte)
7184             create_file("shortone\\longtwo\\augustus", 100);
7185         if (spmap[i].loste)
7186             create_file("longone\\shorttwo\\augustus", 150);
7187         if (spmap[i].lolte)
7188             create_file("longone\\longtwo\\augustus", 200);
7189
7190         r = MsiInstallProductA(msifile, NULL);
7191         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
7192         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
7193            "%d: Expected %d, got %d\n", i, spmap[i].size,
7194            get_pf_file_size("msitest\\augustus"));
7195
7196         if (r == ERROR_SUCCESS)
7197         {
7198             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
7199             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
7200         }
7201         else
7202         {
7203             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
7204             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
7205         }
7206
7207         DeleteFileA("shortone\\shorttwo\\augustus");
7208         DeleteFileA("shortone\\longtwo\\augustus");
7209         DeleteFileA("longone\\shorttwo\\augustus");
7210         DeleteFileA("longone\\longtwo\\augustus");
7211         RemoveDirectoryA("shortone\\shorttwo");
7212         RemoveDirectoryA("shortone\\longtwo");
7213         RemoveDirectoryA("longone\\shorttwo");
7214         RemoveDirectoryA("longone\\longtwo");
7215         RemoveDirectoryA("shortone");
7216         RemoveDirectoryA("longone");
7217     }
7218
7219     DeleteFileA(msifile);
7220 }
7221
7222 static void test_MsiConfigureProductEx(void)
7223 {
7224     UINT r;
7225     LONG res;
7226     DWORD type, size;
7227     HKEY props, source;
7228     CHAR keypath[MAX_PATH * 2];
7229     CHAR localpack[MAX_PATH];
7230
7231     if (on_win9x)
7232     {
7233         win_skip("Different registry keys on Win9x and WinMe\n");
7234         return;
7235     }
7236
7237     CreateDirectoryA("msitest", NULL);
7238     create_file("msitest\\hydrogen", 500);
7239     create_file("msitest\\helium", 500);
7240     create_file("msitest\\lithium", 500);
7241
7242     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7243
7244     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7245
7246     /* NULL szProduct */
7247     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
7248                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7249     ok(r == ERROR_INVALID_PARAMETER,
7250        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7251
7252     /* empty szProduct */
7253     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
7254                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7255     ok(r == ERROR_INVALID_PARAMETER,
7256        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7257
7258     /* garbage szProduct */
7259     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
7260                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7261     ok(r == ERROR_INVALID_PARAMETER,
7262        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7263
7264     /* guid without brackets */
7265     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7266                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7267                                "PROPVAR=42");
7268     ok(r == ERROR_INVALID_PARAMETER,
7269        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7270
7271     /* guid with brackets */
7272     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7273                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7274                                "PROPVAR=42");
7275     ok(r == ERROR_UNKNOWN_PRODUCT,
7276        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7277
7278     /* same length as guid, but random */
7279     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
7280                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7281                                "PROPVAR=42");
7282     ok(r == ERROR_UNKNOWN_PRODUCT,
7283        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7284
7285     /* product not installed yet */
7286     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7287                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7288                                "PROPVAR=42");
7289     ok(r == ERROR_UNKNOWN_PRODUCT,
7290        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7291
7292     /* install the product, per-user unmanaged */
7293     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7294     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7295     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7296     ok(pf_exists("msitest\\helium"), "File not installed\n");
7297     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7298     ok(pf_exists("msitest"), "File not installed\n");
7299
7300     /* product is installed per-user managed, remove it */
7301     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7302                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7303                                "PROPVAR=42");
7304     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7305     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7306     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7307     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7308     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7309
7310     /* product has been removed */
7311     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7312                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7313                                "PROPVAR=42");
7314     ok(r == ERROR_UNKNOWN_PRODUCT,
7315        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7316
7317     /* install the product, machine */
7318     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7319     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7320     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7321     ok(pf_exists("msitest\\helium"), "File not installed\n");
7322     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7323     ok(pf_exists("msitest"), "File not installed\n");
7324
7325     /* product is installed machine, remove it */
7326     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7327                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7328                                "PROPVAR=42");
7329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7330     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7331     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7332     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7333     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7334
7335     /* product has been removed */
7336     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7337                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7338                                "PROPVAR=42");
7339     ok(r == ERROR_UNKNOWN_PRODUCT,
7340        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7341
7342     /* install the product, machine */
7343     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7345     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7346     ok(pf_exists("msitest\\helium"), "File not installed\n");
7347     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7348     ok(pf_exists("msitest"), "File not installed\n");
7349
7350     DeleteFileA(msifile);
7351
7352     /* local msifile is removed */
7353     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7354                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7355                                "PROPVAR=42");
7356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7357     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7358     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7359     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7360     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7361
7362     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7363
7364     /* install the product, machine */
7365     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7366     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7367     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7368     ok(pf_exists("msitest\\helium"), "File not installed\n");
7369     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7370     ok(pf_exists("msitest"), "File not installed\n");
7371
7372     DeleteFileA(msifile);
7373
7374     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7375     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7376     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7377
7378     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7380
7381     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7382                          (const BYTE *)"C:\\idontexist.msi", 18);
7383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7384
7385     /* LocalPackage is used to find the cached msi package */
7386     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7387                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7388                                "PROPVAR=42");
7389     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7390        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7391     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7392     ok(pf_exists("msitest\\helium"), "File not installed\n");
7393     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7394     ok(pf_exists("msitest"), "File not installed\n");
7395
7396     RegCloseKey(props);
7397     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7398
7399     /* LastUsedSource (local msi package) can be used as a last resort */
7400     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7401                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7402                                "PROPVAR=42");
7403     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7404     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7405     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7406     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7407     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7408
7409     /* install the product, machine */
7410     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7412     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7413     ok(pf_exists("msitest\\helium"), "File not installed\n");
7414     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7415     ok(pf_exists("msitest"), "File not installed\n");
7416
7417     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7418     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7419     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7420
7421     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7423
7424     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7425                          (const BYTE *)"C:\\idontexist.msi", 18);
7426     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7427
7428     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
7429     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
7430
7431     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
7432     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7433
7434     type = REG_SZ;
7435     size = MAX_PATH;
7436     res = RegQueryValueExA(source, "PackageName", NULL, &type,
7437                            (LPBYTE)localpack, &size);
7438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7439
7440     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7441                          (const BYTE *)"idontexist.msi", 15);
7442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7443
7444     /* SourceList is altered */
7445     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7446                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7447                                "PROPVAR=42");
7448     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7449        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7450     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7451     ok(pf_exists("msitest\\helium"), "File not installed\n");
7452     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7453     ok(pf_exists("msitest"), "File not installed\n");
7454
7455     /* restore the SourceList */
7456     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7457                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
7458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7459
7460     /* finally remove the product */
7461     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7462                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7463                                "PROPVAR=42");
7464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7465     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7466     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7467     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7468     ok(!delete_pf("msitest", FALSE), "File not removed\n");
7469
7470     DeleteFileA(msifile);
7471     RegCloseKey(source);
7472     RegCloseKey(props);
7473     DeleteFileA("msitest\\hydrogen");
7474     DeleteFileA("msitest\\helium");
7475     DeleteFileA("msitest\\lithium");
7476     RemoveDirectoryA("msitest");
7477 }
7478
7479 static void test_missingcomponent(void)
7480 {
7481     UINT r;
7482
7483     CreateDirectoryA("msitest", NULL);
7484     create_file("msitest\\hydrogen", 500);
7485     create_file("msitest\\helium", 500);
7486     create_file("msitest\\lithium", 500);
7487     create_file("beryllium", 500);
7488
7489     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
7490
7491     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7492
7493     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7494     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7495     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7496     ok(pf_exists("msitest\\helium"), "File not installed\n");
7497     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7498     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7499     ok(pf_exists("msitest"), "File not installed\n");
7500
7501     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
7502     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7503     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7504     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7505     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7506     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7507     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7508
7509     DeleteFileA(msifile);
7510     DeleteFileA("msitest\\hydrogen");
7511     DeleteFileA("msitest\\helium");
7512     DeleteFileA("msitest\\lithium");
7513     DeleteFileA("beryllium");
7514     RemoveDirectoryA("msitest");
7515 }
7516
7517 static void test_sourcedirprop(void)
7518 {
7519     UINT r;
7520     CHAR props[MAX_PATH];
7521
7522     CreateDirectoryA("msitest", NULL);
7523     create_file("msitest\\augustus", 500);
7524
7525     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
7526
7527     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7528
7529     r = MsiInstallProductA(msifile, NULL);
7530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7531     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7532     ok(delete_pf("msitest", FALSE), "File installed\n");
7533
7534     DeleteFile("msitest\\augustus");
7535     RemoveDirectory("msitest");
7536
7537     CreateDirectoryA("altsource", NULL);
7538     CreateDirectoryA("altsource\\msitest", NULL);
7539     create_file("altsource\\msitest\\augustus", 500);
7540
7541     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
7542
7543     r = MsiInstallProductA(msifile, props);
7544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7545     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7546     ok(delete_pf("msitest", FALSE), "File installed\n");
7547
7548     DeleteFile(msifile);
7549     DeleteFile("altsource\\msitest\\augustus");
7550     RemoveDirectory("altsource\\msitest");
7551     RemoveDirectory("altsource");
7552 }
7553
7554 static void test_adminimage(void)
7555 {
7556     UINT r;
7557
7558     CreateDirectoryA("msitest", NULL);
7559     CreateDirectoryA("msitest\\first", NULL);
7560     CreateDirectoryA("msitest\\second", NULL);
7561     CreateDirectoryA("msitest\\cabout", NULL);
7562     CreateDirectoryA("msitest\\cabout\\new", NULL);
7563     create_file("msitest\\one.txt", 100);
7564     create_file("msitest\\first\\two.txt", 100);
7565     create_file("msitest\\second\\three.txt", 100);
7566     create_file("msitest\\cabout\\four.txt", 100);
7567     create_file("msitest\\cabout\\new\\five.txt", 100);
7568     create_file("msitest\\filename", 100);
7569     create_file("msitest\\service.exe", 100);
7570
7571     create_database_wordcount(msifile, ai_tables,
7572                               sizeof(ai_tables) / sizeof(msi_table),
7573                               msidbSumInfoSourceTypeAdminImage);
7574
7575     r = MsiInstallProductA(msifile, NULL);
7576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7577
7578     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7579     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7580     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7581     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7582     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7583     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7584     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7585     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7586     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7587     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7588     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7589     ok(delete_pf("msitest", FALSE), "File not installed\n");
7590
7591     DeleteFileA("msitest.msi");
7592     DeleteFileA("msitest\\cabout\\new\\five.txt");
7593     DeleteFileA("msitest\\cabout\\four.txt");
7594     DeleteFileA("msitest\\second\\three.txt");
7595     DeleteFileA("msitest\\first\\two.txt");
7596     DeleteFileA("msitest\\one.txt");
7597     DeleteFileA("msitest\\service.exe");
7598     DeleteFileA("msitest\\filename");
7599     RemoveDirectoryA("msitest\\cabout\\new");
7600     RemoveDirectoryA("msitest\\cabout");
7601     RemoveDirectoryA("msitest\\second");
7602     RemoveDirectoryA("msitest\\first");
7603     RemoveDirectoryA("msitest");
7604 }
7605
7606 static void test_propcase(void)
7607 {
7608     UINT r;
7609
7610     CreateDirectoryA("msitest", NULL);
7611     create_file("msitest\\augustus", 500);
7612
7613     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
7614
7615     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7616
7617     r = MsiInstallProductA(msifile, "MyProp=42");
7618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7619     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
7620     ok(delete_pf("msitest", FALSE), "File not installed\n");
7621
7622     DeleteFile(msifile);
7623     DeleteFile("msitest\\augustus");
7624     RemoveDirectory("msitest");
7625 }
7626
7627 static void test_int_widths( void )
7628 {
7629     static const char int0[] = "int0\ni0\nint0\tint0\n1";
7630     static const char int1[] = "int1\ni1\nint1\tint1\n1";
7631     static const char int2[] = "int2\ni2\nint2\tint2\n1";
7632     static const char int3[] = "int3\ni3\nint3\tint3\n1";
7633     static const char int4[] = "int4\ni4\nint4\tint4\n1";
7634     static const char int5[] = "int5\ni5\nint5\tint5\n1";
7635     static const char int8[] = "int8\ni8\nint8\tint8\n1";
7636
7637     static const struct
7638     {
7639         const char  *data;
7640         unsigned int size;
7641         UINT         ret;
7642     }
7643     tests[] =
7644     {
7645         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
7646         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
7647         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
7648         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
7649         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
7650         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
7651         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
7652     };
7653
7654     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
7655     MSIHANDLE db;
7656     UINT r, i;
7657
7658     GetTempPathA(MAX_PATH, tmpdir);
7659     CreateDirectoryA(tmpdir, NULL);
7660
7661     strcpy(msitable, tmpdir);
7662     strcat(msitable, "\\msitable.idt");
7663
7664     strcpy(msidb, tmpdir);
7665     strcat(msidb, "\\msitest.msi");
7666
7667     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
7668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7669
7670     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
7671     {
7672         write_file(msitable, tests[i].data, tests[i].size);
7673
7674         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
7675         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
7676
7677         r = MsiDatabaseCommit(db);
7678         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7679         DeleteFileA(msitable);
7680     }
7681
7682     MsiCloseHandle(db);
7683     DeleteFileA(msidb);
7684     RemoveDirectoryA(tmpdir);
7685 }
7686
7687 static void test_shortcut(void)
7688 {
7689     UINT r;
7690     HRESULT hr;
7691
7692     create_test_files();
7693     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
7694
7695     r = MsiInstallProductA(msifile, NULL);
7696     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7697
7698     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
7699     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7700
7701     r = MsiInstallProductA(msifile, NULL);
7702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7703
7704     CoUninitialize();
7705
7706     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7707     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7708
7709     r = MsiInstallProductA(msifile, NULL);
7710     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7711
7712     CoUninitialize();
7713
7714     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7715     delete_pf("msitest\\cabout\\new", FALSE);
7716     delete_pf("msitest\\cabout\\four.txt", TRUE);
7717     delete_pf("msitest\\cabout", FALSE);
7718     delete_pf("msitest\\changed\\three.txt", TRUE);
7719     delete_pf("msitest\\changed", FALSE);
7720     delete_pf("msitest\\first\\two.txt", TRUE);
7721     delete_pf("msitest\\first", FALSE);
7722     delete_pf("msitest\\filename", TRUE);
7723     delete_pf("msitest\\one.txt", TRUE);
7724     delete_pf("msitest\\service.exe", TRUE);
7725     delete_pf("msitest\\Shortcut.lnk", TRUE);
7726     delete_pf("msitest", FALSE);
7727     delete_test_files();
7728 }
7729
7730 static void test_envvar(void)
7731 {
7732     UINT r;
7733     HKEY env;
7734     LONG res;
7735     DWORD type, size;
7736     char buffer[16];
7737     UINT i;
7738
7739     if (on_win9x)
7740     {
7741         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
7742         return;
7743     }
7744
7745     create_test_files();
7746     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
7747
7748     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
7749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7750
7751     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
7752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7753
7754     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
7755     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7756
7757     r = MsiInstallProductA(msifile, NULL);
7758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7759
7760     type = REG_NONE;
7761     size = sizeof(buffer);
7762     buffer[0] = 0;
7763     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
7764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7765     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7766     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7767
7768     res = RegDeleteValueA(env, "MSITESTVAR1");
7769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7770
7771     type = REG_NONE;
7772     size = sizeof(buffer);
7773     buffer[0] = 0;
7774     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
7775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7776     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7777     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7778
7779     res = RegDeleteValueA(env, "MSITESTVAR2");
7780     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7781
7782     res = RegDeleteValueA(env, "MSITESTVAR3");
7783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7784
7785     res = RegDeleteValueA(env, "MSITESTVAR4");
7786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7787
7788     res = RegDeleteValueA(env, "MSITESTVAR5");
7789     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7790
7791     res = RegDeleteValueA(env, "MSITESTVAR6");
7792     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7793
7794     res = RegDeleteValueA(env, "MSITESTVAR7");
7795     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7796
7797     res = RegDeleteValueA(env, "MSITESTVAR8");
7798     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7799
7800     res = RegDeleteValueA(env, "MSITESTVAR9");
7801     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7802
7803     res = RegDeleteValueA(env, "MSITESTVAR10");
7804     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7805
7806     i = 11;
7807     while (environment_dat_results[(i-11)]) {
7808         char name[20];
7809         sprintf(name, "MSITESTVAR%d", i);
7810
7811         type = REG_NONE;
7812         size = sizeof(buffer);
7813         buffer[0] = 0;
7814         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
7815         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7816         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
7817         ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n",
7818            i, environment_dat_results[(i-11)], buffer);
7819
7820         res = RegDeleteValueA(env, name);
7821         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
7822         i++;
7823     }
7824
7825
7826     RegCloseKey(env);
7827     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7828     delete_pf("msitest\\cabout\\new", FALSE);
7829     delete_pf("msitest\\cabout\\four.txt", TRUE);
7830     delete_pf("msitest\\cabout", FALSE);
7831     delete_pf("msitest\\changed\\three.txt", TRUE);
7832     delete_pf("msitest\\changed", FALSE);
7833     delete_pf("msitest\\first\\two.txt", TRUE);
7834     delete_pf("msitest\\first", FALSE);
7835     delete_pf("msitest\\filename", TRUE);
7836     delete_pf("msitest\\one.txt", TRUE);
7837     delete_pf("msitest\\service.exe", TRUE);
7838     delete_pf("msitest", FALSE);
7839     delete_test_files();
7840 }
7841
7842 static void test_preselected(void)
7843 {
7844     UINT r;
7845
7846     create_test_files();
7847     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
7848
7849     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
7850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7851
7852     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
7853     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
7854     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
7855     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
7856     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
7857     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
7858     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
7859     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
7860     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
7861     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7862     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
7863     ok(delete_pf("msitest", FALSE), "File not installed\n");
7864
7865     r = MsiInstallProductA(msifile, NULL);
7866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7867
7868     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7869     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7870     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7871     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7872     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7873     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7874     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7875     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7876     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7877     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7878     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7879     ok(delete_pf("msitest", FALSE), "File not installed\n");
7880     delete_test_files();
7881 }
7882
7883 static void test_installed_prop(void)
7884 {
7885     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
7886     UINT r;
7887
7888     create_test_files();
7889     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
7890
7891     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7892
7893     r = MsiInstallProductA(msifile, "FULL=1");
7894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7895
7896     r = MsiInstallProductA(msifile, "FULL=1");
7897     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7898
7899     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
7900     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
7901
7902     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7903     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7904     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7905     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7906     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7907     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7908     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7909     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7910     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7911     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7912     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7913     ok(delete_pf("msitest", FALSE), "File not installed\n");
7914
7915     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7917
7918     delete_test_files();
7919 }
7920
7921 static void test_allusers_prop(void)
7922 {
7923     UINT r;
7924
7925     create_test_files();
7926     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
7927
7928     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7929
7930     /* ALLUSERS property unset */
7931     r = MsiInstallProductA(msifile, "FULL=1");
7932     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7933
7934     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7935     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7936     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7937     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7938     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7939     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7940     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7941     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7942     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7943     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7944     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7945     ok(delete_pf("msitest", FALSE), "File not installed\n");
7946
7947     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7949
7950     delete_test_files();
7951
7952     create_test_files();
7953     create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
7954
7955     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7956
7957     /* ALLUSERS property set to 1 */
7958     r = MsiInstallProductA(msifile, "FULL=1");
7959     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7960
7961     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7962     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7963     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7964     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7965     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7966     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7967     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7968     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7969     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7970     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7971     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7972     ok(delete_pf("msitest", FALSE), "File not installed\n");
7973
7974     r = MsiInstallProductA(msifile, "REMOVE=ALL");
7975     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7976
7977     delete_test_files();
7978
7979     create_test_files();
7980     create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
7981
7982     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7983
7984     /* ALLUSERS property set to 2 */
7985     r = MsiInstallProductA(msifile, "FULL=1");
7986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7987
7988     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7989     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7990     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7991     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7992     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7993     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7994     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7995     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7996     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7997     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
7998     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7999     ok(delete_pf("msitest", FALSE), "File not installed\n");
8000
8001     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8002     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8003
8004     delete_test_files();
8005
8006     create_test_files();
8007     create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
8008
8009     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8010
8011     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
8012     r = MsiInstallProductA(msifile, "FULL=1");
8013     if (r == ERROR_SUCCESS)
8014     {
8015         /* Win9x/WinMe */
8016         win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n");
8017
8018         ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8019         ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8020         ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8021         ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8022         ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8023         ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8024         ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8025         ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8026         ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8027         ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8028         ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8029         ok(delete_pf("msitest", FALSE), "File not installed\n");
8030
8031         r = MsiInstallProductA(msifile, "REMOVE=ALL");
8032         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8033
8034         delete_test_files();
8035     }
8036     else
8037         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8038 }
8039
8040 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
8041 static char rename_ops[]      = "PendingFileRenameOperations";
8042
8043 static void process_pending_renames(HKEY hkey)
8044 {
8045     char *buf, *src, *dst, *buf2, *buf2ptr;
8046     DWORD size, buf2len = 0;
8047     LONG ret;
8048     BOOL found = FALSE;
8049
8050     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
8051     buf = HeapAlloc(GetProcessHeap(), 0, size);
8052     buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
8053     buf[0] = 0;
8054
8055     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
8056     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
8057
8058     for (src = buf; *src; src = dst + strlen(dst) + 1)
8059     {
8060         DWORD flags = MOVEFILE_COPY_ALLOWED;
8061
8062         dst = src + strlen(src) + 1;
8063
8064         if (!strstr(src, "msitest"))
8065         {
8066             lstrcpyA(buf2ptr, src);
8067             buf2len += strlen(src) + 1;
8068             buf2ptr += strlen(src) + 1;
8069             if (*dst)
8070             {
8071                 lstrcpyA(buf2ptr, dst);
8072                 buf2ptr += strlen(dst) + 1;
8073                 buf2len += strlen(dst) + 1;
8074             }
8075             buf2ptr++;
8076             buf2len++;
8077             continue;
8078         }
8079
8080         found = TRUE;
8081
8082         if (*dst == '!')
8083         {
8084             flags |= MOVEFILE_REPLACE_EXISTING;
8085             dst++;
8086         }
8087         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
8088         if (*dst)
8089         {
8090             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
8091             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
8092         }
8093         else
8094             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
8095     }
8096
8097     ok(found, "Expected a 'msitest' entry\n");
8098
8099     if (*buf2)
8100     {
8101         buf2len++;
8102         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len);
8103     }
8104     else
8105         RegDeleteValueA(hkey, rename_ops);
8106
8107     HeapFree(GetProcessHeap(), 0, buf);
8108     HeapFree(GetProcessHeap(), 0, buf2);
8109 }
8110
8111 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
8112 {
8113     DWORD len, data_len = strlen(data);
8114     HANDLE handle;
8115     char buf[128];
8116
8117     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
8118     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
8119
8120     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
8121     {
8122         CloseHandle(handle);
8123         return !memcmp(buf, data, data_len);
8124     }
8125     CloseHandle(handle);
8126     return FALSE;
8127 }
8128
8129 static void test_file_in_use(void)
8130 {
8131     UINT r;
8132     HANDLE file;
8133     HKEY hkey;
8134     char path[MAX_PATH];
8135
8136     if (on_win9x)
8137     {
8138         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
8139         return;
8140     }
8141
8142     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
8143
8144     CreateDirectoryA("msitest", NULL);
8145     create_file("msitest\\maximus", 500);
8146     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
8147
8148     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8149
8150     lstrcpy(path, PROG_FILES_DIR);
8151     lstrcat(path, "\\msitest");
8152     CreateDirectoryA(path, NULL);
8153
8154     lstrcat(path, "\\maximus");
8155     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8156
8157     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8158     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8159     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8160     CloseHandle(file);
8161     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8162
8163     process_pending_renames(hkey);
8164     RegCloseKey(hkey);
8165
8166     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
8167     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8168     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8169
8170     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8171     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8172
8173     DeleteFileA("msitest\\maximus");
8174     delete_test_files();
8175 }
8176
8177 static void test_file_in_use_cab(void)
8178 {
8179     UINT r;
8180     HANDLE file;
8181     HKEY hkey;
8182     char path[MAX_PATH];
8183
8184     if (on_win9x)
8185     {
8186         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
8187         return;
8188     }
8189
8190     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
8191
8192     CreateDirectoryA("msitest", NULL);
8193     create_file("maximus", 500);
8194     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
8195     DeleteFile("maximus");
8196
8197     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
8198
8199     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8200
8201     lstrcpy(path, PROG_FILES_DIR);
8202     lstrcat(path, "\\msitest");
8203     CreateDirectoryA(path, NULL);
8204
8205     lstrcat(path, "\\maximus");
8206     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8207
8208     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8209     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8210     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8211     CloseHandle(file);
8212     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8213
8214     process_pending_renames(hkey);
8215     RegCloseKey(hkey);
8216
8217     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
8218     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8219     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8220
8221     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8223
8224     delete_cab_files();
8225     delete_test_files();
8226 }
8227
8228 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
8229 {
8230     return IDOK;
8231 }
8232
8233 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
8234 {
8235     return IDOK;
8236 }
8237
8238 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
8239 {
8240     return IDOK;
8241 }
8242
8243 static void test_MsiSetExternalUI(void)
8244 {
8245     INSTALLUI_HANDLERA ret_a;
8246     INSTALLUI_HANDLERW ret_w;
8247     INSTALLUI_HANDLER_RECORD prev;
8248     UINT error;
8249
8250     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8251     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8252
8253     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8254     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
8255
8256     /* Not present before Installer 3.1 */
8257     if (!pMsiSetExternalUIRecord) {
8258         win_skip("MsiSetExternalUIRecord is not available\n");
8259         return;
8260     }
8261
8262     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8263     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8264     ok(prev == NULL, "expected NULL, got %p\n", prev);
8265
8266     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8267     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
8268     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8269     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8270
8271     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8272     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8273
8274     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8275     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
8276
8277     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8278     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8279
8280     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8281     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8282
8283     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8284     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8285     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8286     ok(prev == NULL, "expected NULL, got %p\n", prev);
8287
8288     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8289     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8290
8291     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8292     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8293
8294     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8295     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
8296     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8297     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8298
8299     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
8300     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8301
8302     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
8303     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8304 }
8305
8306 static void test_feature_override(void)
8307 {
8308     UINT r;
8309
8310     create_test_files();
8311     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
8312
8313     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
8314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8315
8316     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8317     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
8318     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8319     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
8320     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8321     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
8322     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8323     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
8324     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8325     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8326     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8327     ok(delete_pf("msitest", FALSE), "File not installed\n");
8328
8329     delete_test_files();
8330
8331     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest");
8332 }
8333
8334 static void test_create_folder(void)
8335 {
8336     UINT r;
8337
8338     create_test_files();
8339     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
8340
8341     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8342
8343     r = MsiInstallProductA(msifile, NULL);
8344     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8345
8346     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8347     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8348     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8349     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8350     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8351     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8352     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8353     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8354     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8355     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8356     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8357     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8358
8359     r = MsiInstallProductA(msifile, "LOCAL=Two");
8360     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8361
8362     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8363     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8364     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8365     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8366     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8367     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8368     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8369     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8370     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8371     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8372     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8373     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8374
8375     delete_test_files();
8376 }
8377
8378 static void test_remove_folder(void)
8379 {
8380     UINT r;
8381
8382     create_test_files();
8383     create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table));
8384
8385     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8386
8387     r = MsiInstallProductA(msifile, NULL);
8388     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8389
8390     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8391     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8392     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8393     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8394     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8395     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8396     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8397     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8398     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8399     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8400     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8401     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8402
8403     r = MsiInstallProductA(msifile, "LOCAL=Two");
8404     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8405
8406     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8407     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8408     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8409     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8410     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8411     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8412     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8413     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8414     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8415     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8416     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8417     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8418
8419     delete_test_files();
8420 }
8421
8422 static void test_start_services(void)
8423 {
8424     UINT r;
8425     SC_HANDLE scm, service;
8426     BOOL ret;
8427     DWORD error = ERROR_SUCCESS;
8428
8429     if (on_win9x)
8430     {
8431         win_skip("Services are not implemented on Win9x and WinMe\n");
8432         return;
8433     }
8434     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8435     ok(scm != NULL, "Failed to open the SC Manager\n");
8436     if (!scm) return;
8437
8438     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8439     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
8440     {
8441         win_skip("The 'Spooler' service does not exist\n");
8442         CloseServiceHandle(scm);
8443         return;
8444     }
8445     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
8446     if (!service) {
8447         CloseServiceHandle(scm);
8448         return;
8449     }
8450
8451     ret = StartService(service, 0, NULL);
8452     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
8453     {
8454         skip("Terminal service not available, skipping test\n");
8455         CloseServiceHandle(service);
8456         CloseServiceHandle(scm);
8457         return;
8458     }
8459
8460     CloseServiceHandle(service);
8461     CloseServiceHandle(scm);
8462
8463     create_test_files();
8464     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
8465
8466     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8467
8468     r = MsiInstallProductA(msifile, NULL);
8469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8470
8471     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8472     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8473     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8474     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8475     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8476     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8477     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8478     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8479     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8480     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8481     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8482     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8483
8484     delete_test_files();
8485
8486     if (error == ERROR_SUCCESS)
8487     {
8488         SERVICE_STATUS status;
8489
8490         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8491         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8492
8493         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
8494         ok(ret, "ControlService failed %u\n", GetLastError());
8495
8496         CloseServiceHandle(service);
8497         CloseServiceHandle(scm);
8498     }
8499 }
8500
8501 static void test_delete_services(void)
8502 {
8503     UINT r;
8504
8505     create_test_files();
8506     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
8507
8508     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8509
8510     r = MsiInstallProductA(msifile, NULL);
8511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8512
8513     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8514     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8515     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8516     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8517     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8518     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8519     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8520     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8521     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8522     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8523     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8524     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8525
8526     delete_test_files();
8527 }
8528
8529 static void test_self_registration(void)
8530 {
8531     UINT r;
8532
8533     create_test_files();
8534     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
8535
8536     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8537
8538     r = MsiInstallProductA(msifile, NULL);
8539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8540
8541     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8542     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8543     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8544     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8545     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8546     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8547     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8548     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8549     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8550     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8551     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8552     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8553
8554     delete_test_files();
8555 }
8556
8557 static void test_register_font(void)
8558 {
8559     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
8560     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
8561     LONG ret;
8562     HKEY key;
8563     UINT r;
8564
8565     create_test_files();
8566     create_file("msitest\\font.ttf", 1000);
8567     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
8568
8569     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8570
8571     r = MsiInstallProductA(msifile, NULL);
8572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8573
8574     ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key);
8575     if (ret)
8576         RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key);
8577
8578     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8579     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8580
8581     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8583
8584     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8585
8586     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8587     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8588
8589     RegDeleteValueA(key, "msi test font");
8590     RegCloseKey(key);
8591     DeleteFileA("msitest\\font.ttf");
8592     delete_test_files();
8593 }
8594
8595 static void test_validate_product_id(void)
8596 {
8597     UINT r;
8598
8599     create_test_files();
8600     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
8601
8602     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8603
8604     r = MsiInstallProductA(msifile, NULL);
8605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8606
8607     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
8608     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8609
8610     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
8611     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8612
8613     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
8614     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8615
8616     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8617     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8618     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8619     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8620     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8621     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8622     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8623     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8624     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8625     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8626     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8627     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8628
8629     delete_test_files();
8630 }
8631
8632 static void test_install_remove_odbc(void)
8633 {
8634     UINT r;
8635
8636     create_test_files();
8637     create_file("msitest\\ODBCdriver.dll", 1000);
8638     create_file("msitest\\ODBCdriver2.dll", 1000);
8639     create_file("msitest\\ODBCtranslator.dll", 1000);
8640     create_file("msitest\\ODBCtranslator2.dll", 1000);
8641     create_file("msitest\\ODBCsetup.dll", 1000);
8642     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
8643
8644     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8645
8646     r = MsiInstallProductA(msifile, NULL);
8647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8648
8649     ok(delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not created\n");
8650     ok(delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not created\n");
8651     ok(delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not created\n");
8652     ok(delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not created\n");
8653     ok(delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not created\n");
8654     ok(delete_pf("msitest", FALSE), "directory not created\n");
8655
8656     DeleteFileA("msitest\\ODBCdriver.dll");
8657     DeleteFileA("msitest\\ODBCdriver2.dll");
8658     DeleteFileA("msitest\\ODBCtranslator.dll");
8659     DeleteFileA("msitest\\ODBCtranslator2.dll");
8660     DeleteFileA("msitest\\ODBCsetup.dll");
8661     delete_test_files();
8662 }
8663
8664 static void test_register_typelib(void)
8665 {
8666     UINT r;
8667
8668     create_test_files();
8669     create_file("msitest\\typelib.dll", 1000);
8670     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
8671
8672     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8673
8674     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
8675     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8676
8677     r = MsiInstallProductA(msifile, NULL);
8678     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8679
8680     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8681     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8682
8683     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
8684     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8685
8686     DeleteFileA("msitest\\typelib.dll");
8687     delete_test_files();
8688 }
8689
8690 static void test_create_remove_shortcut(void)
8691 {
8692     UINT r;
8693
8694     create_test_files();
8695     create_file("msitest\\target.txt", 1000);
8696     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
8697
8698     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8699
8700     r = MsiInstallProductA(msifile, NULL);
8701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8702
8703     ok(pf_exists("msitest\\target.txt"), "file not created\n");
8704     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
8705
8706     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8708
8709     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
8710     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
8711     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8712
8713     DeleteFileA("msitest\\target.txt");
8714     delete_test_files();
8715 }
8716
8717 static void test_publish_components(void)
8718 {
8719     static char keypath[] =
8720         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
8721
8722     UINT r;
8723     LONG res;
8724     HKEY key;
8725
8726     create_test_files();
8727     create_file("msitest\\english.txt", 1000);
8728     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
8729
8730     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8731
8732     r = MsiInstallProductA(msifile, NULL);
8733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8734
8735     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8736     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
8737
8738     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
8739     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
8740     RegCloseKey(key);
8741
8742     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8743     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8744
8745     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8746     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
8747
8748     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
8749     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8750
8751     DeleteFileA("msitest\\english.txt");
8752     delete_test_files();
8753 }
8754
8755 static void test_remove_duplicate_files(void)
8756 {
8757     UINT r;
8758
8759     create_test_files();
8760     create_file("msitest\\original.txt", 1000);
8761     create_file("msitest\\original2.txt", 1000);
8762     create_file("msitest\\original3.txt", 1000);
8763     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
8764
8765     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8766
8767     r = MsiInstallProductA(msifile, NULL);
8768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8769
8770     ok(pf_exists("msitest\\original.txt"), "file not created\n");
8771     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
8772     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
8773     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
8774     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
8775
8776     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8778
8779     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
8780     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
8781     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
8782     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
8783     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
8784     ok(delete_pf("msitest", FALSE), "directory removed\n");
8785
8786     DeleteFileA("msitest\\original.txt");
8787     DeleteFileA("msitest\\original2.txt");
8788     DeleteFileA("msitest\\original3.txt");
8789     delete_test_files();
8790 }
8791
8792 static void test_remove_registry_values(void)
8793 {
8794     UINT r;
8795     LONG res;
8796     HKEY key;
8797
8798     create_test_files();
8799     create_file("msitest\\registry.txt", 1000);
8800     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
8801
8802     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8803
8804     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8805     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
8806     RegCloseKey(key);
8807
8808     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8809     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
8810     RegCloseKey(key);
8811
8812     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8813     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8814     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
8815     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8816     RegCloseKey(key);
8817
8818     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8819     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
8820     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
8821     RegCloseKey(key);
8822
8823     r = MsiInstallProductA(msifile, NULL);
8824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8825
8826     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8827     ok(res == ERROR_SUCCESS, "key removed\n");
8828     RegCloseKey(key);
8829
8830     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8831     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8832
8833     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8835     RegCloseKey(key);
8836
8837     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8838     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8839
8840     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
8841     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8842
8843     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
8844     ok(res == ERROR_SUCCESS, "key removed\n");
8845     RegCloseKey(key);
8846
8847     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
8848     ok(res == ERROR_SUCCESS, "key removed\n");
8849     RegCloseKey(key);
8850
8851     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
8852     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
8853
8854     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA");
8855     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2");
8856     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine");
8857
8858     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
8859     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8860
8861     DeleteFileA("msitest\\registry.txt");
8862     delete_test_files();
8863 }
8864
8865 static void test_find_related_products(void)
8866 {
8867     UINT r;
8868
8869     create_test_files();
8870     create_file("msitest\\product.txt", 1000);
8871     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
8872
8873     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8874
8875     r = MsiInstallProductA(msifile, NULL);
8876     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8877
8878     /* install again, so it finds the upgrade code */
8879     r = MsiInstallProductA(msifile, NULL);
8880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8881
8882     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8883     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8884
8885     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
8886     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8887
8888     DeleteFileA("msitest\\product.txt");
8889     delete_test_files();
8890 }
8891
8892 static void test_remove_ini_values(void)
8893 {
8894     UINT r;
8895     DWORD len;
8896     char inifile[MAX_PATH], buf[0x10];
8897     HANDLE file;
8898     BOOL ret;
8899
8900     create_test_files();
8901     create_file("msitest\\inifile.txt", 1000);
8902     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
8903
8904     lstrcpyA(inifile, PROG_FILES_DIR);
8905     lstrcatA(inifile, "\\msitest");
8906     CreateDirectoryA(inifile, NULL);
8907     lstrcatA(inifile, "\\test.ini");
8908     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
8909     CloseHandle(file);
8910
8911     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
8912     ok(ret, "failed to write profile string %u\n", GetLastError());
8913
8914     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
8915     ok(ret, "failed to write profile string %u\n", GetLastError());
8916
8917     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8918
8919     r = MsiInstallProductA(msifile, NULL);
8920     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8921
8922     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
8923     ok(len == 6, "got %u expected 6\n", len);
8924
8925     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
8926     ok(!len, "got %u expected 0\n", len);
8927
8928     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8929     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8930
8931     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
8932     ok(!len, "got %u expected 0\n", len);
8933
8934     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
8935     ok(!len, "got %u expected 0\n", len);
8936
8937     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
8938     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
8939     ok(delete_pf("msitest", FALSE), "directory removed\n");
8940
8941     DeleteFileA("msitest\\inifile.txt");
8942     delete_test_files();
8943 }
8944
8945 static void test_remove_env_strings(void)
8946 {
8947     UINT r;
8948     LONG res;
8949     HKEY key;
8950     DWORD type, size;
8951     char buffer[0x10];
8952
8953     if (on_win9x)
8954     {
8955         win_skip("Environment variables are handled differently on win9x and winme\n");
8956         return;
8957     }
8958
8959     create_test_files();
8960     create_file("msitest\\envvar.txt", 1000);
8961     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
8962
8963     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8964
8965     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
8966     ok(!res, "failed to open environment key %d\n", res);
8967
8968     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
8969     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
8970     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
8971     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
8972     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
8973
8974     RegCloseKey(key);
8975
8976     r = MsiInstallProductA(msifile, NULL);
8977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8978
8979     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
8980     ok(!res, "failed to open environment key %d\n", res);
8981
8982     type = REG_NONE;
8983     buffer[0] = 0;
8984     size = sizeof(buffer);
8985     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
8986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8987     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8988     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8989
8990     type = REG_NONE;
8991     buffer[0] = 0;
8992     size = sizeof(buffer);
8993     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
8994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8995     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
8996     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
8997
8998     type = REG_NONE;
8999     buffer[0] = 0;
9000     size = sizeof(buffer);
9001     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
9002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9003     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9004     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9005
9006     type = REG_NONE;
9007     buffer[0] = 0;
9008     size = sizeof(buffer);
9009     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
9010     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9011     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9012     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9013
9014     type = REG_NONE;
9015     buffer[0] = 0;
9016     size = sizeof(buffer);
9017     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
9018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9019     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9020     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9021
9022     RegCloseKey(key);
9023
9024     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9026
9027     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
9028     ok(!res, "failed to open environment key %d\n", res);
9029
9030     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
9031     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9032
9033     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
9034     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9035
9036     type = REG_NONE;
9037     buffer[0] = 0;
9038     size = sizeof(buffer);
9039     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
9040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9041     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9042     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9043     RegDeleteValueA(key, "MSITESTVAR3");
9044
9045     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
9046     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9047
9048     type = REG_NONE;
9049     buffer[0] = 0;
9050     size = sizeof(buffer);
9051     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
9052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9053     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9054     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9055     RegDeleteValueA(key, "MSITESTVAR5");
9056
9057     RegCloseKey(key);
9058
9059     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
9060     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9061
9062     DeleteFileA("msitest\\envvar.txt");
9063     delete_test_files();
9064 }
9065
9066 static void test_register_class_info(void)
9067 {
9068     UINT r;
9069     LONG res;
9070     HKEY hkey;
9071
9072     create_test_files();
9073     create_file("msitest\\class.txt", 1000);
9074     create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table));
9075
9076     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9077
9078     r = MsiInstallProductA(msifile, NULL);
9079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9080
9081     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9082     ok(res == ERROR_SUCCESS, "key not created\n");
9083     RegCloseKey(hkey);
9084
9085     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9086     ok(res == ERROR_SUCCESS, "key not created\n");
9087     RegCloseKey(hkey);
9088
9089     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
9090     ok(res == ERROR_SUCCESS, "key not created\n");
9091     RegCloseKey(hkey);
9092
9093     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9095
9096     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9097     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9098
9099     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9100     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9101
9102     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
9103     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9104
9105     ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n");
9106     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9107     delete_test_files();
9108 }
9109
9110 static void test_register_extension_info(void)
9111 {
9112     UINT r;
9113     LONG res;
9114     HKEY hkey;
9115
9116     create_test_files();
9117     create_file("msitest\\extension.txt", 1000);
9118     create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table));
9119
9120     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9121
9122     r = MsiInstallProductA(msifile, NULL);
9123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9124
9125     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
9126     ok(res == ERROR_SUCCESS, "key not created\n");
9127     RegCloseKey(hkey);
9128
9129     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey);
9130     ok(res == ERROR_SUCCESS, "key not created\n");
9131     RegCloseKey(hkey);
9132
9133     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9135
9136     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
9137     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9138
9139     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey);
9140     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9141
9142     ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n");
9143     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9144     delete_test_files();
9145 }
9146
9147 START_TEST(install)
9148 {
9149     DWORD len;
9150     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
9151     STATEMGRSTATUS status;
9152     BOOL ret = FALSE;
9153
9154     init_functionpointers();
9155
9156     on_win9x = check_win9x();
9157
9158     GetCurrentDirectoryA(MAX_PATH, prev_path);
9159     GetTempPath(MAX_PATH, temp_path);
9160     SetCurrentDirectoryA(temp_path);
9161
9162     lstrcpyA(CURR_DIR, temp_path);
9163     len = lstrlenA(CURR_DIR);
9164
9165     if(len && (CURR_DIR[len - 1] == '\\'))
9166         CURR_DIR[len - 1] = 0;
9167
9168     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
9169
9170     /* Create a restore point ourselves so we circumvent the multitude of restore points
9171      * that would have been created by all the installation and removal tests.
9172      */
9173     if (pSRSetRestorePointA)
9174     {
9175         memset(&status, 0, sizeof(status));
9176         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
9177     }
9178
9179     /* Create only one log file and don't append. We have to pass something
9180      * for the log mode for this to work. The logfile needs to have an absolute
9181      * path otherwise we still end up with some extra logfiles as some tests
9182      * change the current directory.
9183      */
9184     lstrcpyA(log_file, temp_path);
9185     lstrcatA(log_file, "\\msitest.log");
9186     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
9187
9188     test_MsiInstallProduct();
9189     test_MsiSetComponentState();
9190     test_packagecoltypes();
9191     test_continuouscabs();
9192     test_caborder();
9193     test_mixedmedia();
9194     test_samesequence();
9195     test_uiLevelFlags();
9196     test_readonlyfile();
9197     test_readonlyfile_cab();
9198     test_setdirproperty();
9199     test_cabisextracted();
9200     test_concurrentinstall();
9201     test_setpropertyfolder();
9202     test_publish_registerproduct();
9203     test_publish_publishproduct();
9204     test_publish_publishfeatures();
9205     test_publish_registeruser();
9206     test_publish_processcomponents();
9207     test_publish();
9208     test_publishsourcelist();
9209     test_transformprop();
9210     test_currentworkingdir();
9211     test_admin();
9212     test_adminprops();
9213     test_removefiles();
9214     test_movefiles();
9215     test_missingcab();
9216     test_duplicatefiles();
9217     test_writeregistryvalues();
9218     test_sourcefolder();
9219     test_customaction51();
9220     test_installstate();
9221     test_sourcepath();
9222     test_MsiConfigureProductEx();
9223     test_missingcomponent();
9224     test_sourcedirprop();
9225     test_adminimage();
9226     test_propcase();
9227     test_int_widths();
9228     test_shortcut();
9229     test_envvar();
9230     test_lastusedsource();
9231     test_preselected();
9232     test_installed_prop();
9233     test_file_in_use();
9234     test_file_in_use_cab();
9235     test_MsiSetExternalUI();
9236     test_allusers_prop();
9237     test_feature_override();
9238     test_create_folder();
9239     test_remove_folder();
9240     test_start_services();
9241     test_delete_services();
9242     test_self_registration();
9243     test_register_font();
9244     test_validate_product_id();
9245     test_install_remove_odbc();
9246     test_register_typelib();
9247     test_create_remove_shortcut();
9248     test_publish_components();
9249     test_remove_duplicate_files();
9250     test_remove_registry_values();
9251     test_find_related_products();
9252     test_remove_ini_values();
9253     test_remove_env_strings();
9254     test_register_class_info();
9255     test_register_extension_info();
9256
9257     DeleteFileA(log_file);
9258
9259     if (pSRSetRestorePointA && ret)
9260     {
9261         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
9262         if (ret)
9263             remove_restore_point(status.llSequenceNumber);
9264     }
9265     FreeLibrary(hsrclient);
9266
9267     SetCurrentDirectoryA(prev_path);
9268 }