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