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