msi: Add a test for MsiSetFeatureState.
[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 #include <shlobj.h>
34
35 #include "wine/test.h"
36
37 static UINT (WINAPI *pMsiQueryComponentStateA)
38     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
39 static UINT (WINAPI *pMsiSetExternalUIRecord)
40     (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
41 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
42     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
43 static UINT (WINAPI *pMsiSourceListGetInfoA)
44     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
45
46 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
47
48 static HMODULE hsrclient = 0;
49 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
50 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
51
52 static BOOL on_win9x = FALSE;
53
54 static const char *msifile = "msitest.msi";
55 static const char *msifile2 = "winetest2.msi";
56 static const char *mstfile = "winetest.mst";
57 static CHAR CURR_DIR[MAX_PATH];
58 static CHAR PROG_FILES_DIR[MAX_PATH];
59 static CHAR COMMON_FILES_DIR[MAX_PATH];
60 static CHAR APP_DATA_DIR[MAX_PATH];
61 static CHAR WINDOWS_DIR[MAX_PATH];
62
63 /* msi database data */
64
65 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
66                                     "s72\tS38\ts72\ti2\tS255\tS72\n"
67                                     "Component\tComponent\n"
68                                     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
69                                     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
70                                     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
71                                     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
72                                     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
73                                     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
74                                     "component\t\tMSITESTDIR\t0\t1\tfile\n"
75                                     "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
76
77 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
78                                     "s72\tS72\tl255\n"
79                                     "Directory\tDirectory\n"
80                                     "CABOUTDIR\tMSITESTDIR\tcabout\n"
81                                     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
82                                     "FIRSTDIR\tMSITESTDIR\tfirst\n"
83                                     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
84                                     "NEWDIR\tCABOUTDIR\tnew\n"
85                                     "ProgramFilesFolder\tTARGETDIR\t.\n"
86                                     "TARGETDIR\t\tSourceDir";
87
88 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
89                                   "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
90                                   "Feature\tFeature\n"
91                                   "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
92                                   "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
93                                   "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
94                                   "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
95                                   "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
96                                   "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
97                                   "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
98
99 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
100                                        "s38\ts72\n"
101                                        "FeatureComponents\tFeature_\tComponent_\n"
102                                        "Five\tFive\n"
103                                        "Four\tFour\n"
104                                        "One\tOne\n"
105                                        "Three\tThree\n"
106                                        "Two\tTwo\n"
107                                        "feature\tcomponent\n"
108                                        "service_feature\tservice_comp\n";
109
110 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
111                                "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
112                                "File\tFile\n"
113                                "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
114                                "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
115                                "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
116                                "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
117                                "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
118                                "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
119                                "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
120
121 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
122                                            "s72\tS255\tI2\n"
123                                            "InstallExecuteSequence\tAction\n"
124                                            "AllocateRegistrySpace\tNOT Installed\t1550\n"
125                                            "CostFinalize\t\t1000\n"
126                                            "CostInitialize\t\t800\n"
127                                            "FileCost\t\t900\n"
128                                            "ResolveSource\t\t950\n"
129                                            "MoveFiles\t\t1700\n"
130                                            "InstallFiles\t\t4000\n"
131                                            "DuplicateFiles\t\t4500\n"
132                                            "WriteEnvironmentStrings\t\t4550\n"
133                                            "CreateShortcuts\t\t4600\n"
134                                            "InstallServices\t\t5000\n"
135                                            "InstallFinalize\t\t6600\n"
136                                            "InstallInitialize\t\t1500\n"
137                                            "InstallValidate\t\t1400\n"
138                                            "LaunchConditions\t\t100\n"
139                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
140
141 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
142                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
143                                 "Media\tDiskId\n"
144                                 "1\t3\t\t\tDISK1\t\n"
145                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
146
147 static const CHAR property_dat[] = "Property\tValue\n"
148                                    "s72\tl0\n"
149                                    "Property\tProperty\n"
150                                    "DefaultUIFont\tDlgFont8\n"
151                                    "HASUIRUN\t0\n"
152                                    "INSTALLLEVEL\t3\n"
153                                    "InstallMode\tTypical\n"
154                                    "Manufacturer\tWine\n"
155                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
156                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
157                                    "ProductID\tnone\n"
158                                    "ProductLanguage\t1033\n"
159                                    "ProductName\tMSITEST\n"
160                                    "ProductVersion\t1.1.1\n"
161                                    "PROMPTROLLBACKCOST\tP\n"
162                                    "Setup\tSetup\n"
163                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
164                                    "AdminProperties\tPOSTADMIN\n"
165                                    "ROOTDRIVE\tC:\\\n"
166                                    "SERVNAME\tTestService\n"
167                                    "SERVDISP\tTestServiceDisp\n";
168
169 static const CHAR aup_property_dat[] = "Property\tValue\n"
170                                        "s72\tl0\n"
171                                        "Property\tProperty\n"
172                                        "DefaultUIFont\tDlgFont8\n"
173                                        "HASUIRUN\t0\n"
174                                        "ALLUSERS\t1\n"
175                                        "INSTALLLEVEL\t3\n"
176                                        "InstallMode\tTypical\n"
177                                        "Manufacturer\tWine\n"
178                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
179                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
180                                        "ProductID\tnone\n"
181                                        "ProductLanguage\t1033\n"
182                                        "ProductName\tMSITEST\n"
183                                        "ProductVersion\t1.1.1\n"
184                                        "PROMPTROLLBACKCOST\tP\n"
185                                        "Setup\tSetup\n"
186                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
187                                        "AdminProperties\tPOSTADMIN\n"
188                                        "ROOTDRIVE\tC:\\\n"
189                                        "SERVNAME\tTestService\n"
190                                        "SERVDISP\tTestServiceDisp\n";
191
192 static const CHAR aup2_property_dat[] = "Property\tValue\n"
193                                         "s72\tl0\n"
194                                         "Property\tProperty\n"
195                                         "DefaultUIFont\tDlgFont8\n"
196                                         "HASUIRUN\t0\n"
197                                         "ALLUSERS\t2\n"
198                                         "INSTALLLEVEL\t3\n"
199                                         "InstallMode\tTypical\n"
200                                         "Manufacturer\tWine\n"
201                                         "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
202                                         "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
203                                         "ProductID\tnone\n"
204                                         "ProductLanguage\t1033\n"
205                                         "ProductName\tMSITEST\n"
206                                         "ProductVersion\t1.1.1\n"
207                                         "PROMPTROLLBACKCOST\tP\n"
208                                         "Setup\tSetup\n"
209                                         "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
210                                         "AdminProperties\tPOSTADMIN\n"
211                                         "ROOTDRIVE\tC:\\\n"
212                                         "SERVNAME\tTestService\n"
213                                         "SERVDISP\tTestServiceDisp\n";
214
215 static const CHAR icon_property_dat[] = "Property\tValue\n"
216                                         "s72\tl0\n"
217                                         "Property\tProperty\n"
218                                         "DefaultUIFont\tDlgFont8\n"
219                                         "HASUIRUN\t0\n"
220                                         "INSTALLLEVEL\t3\n"
221                                         "InstallMode\tTypical\n"
222                                         "Manufacturer\tWine\n"
223                                         "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
224                                         "ProductCode\t{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}\n"
225                                         "ProductID\tnone\n"
226                                         "ProductLanguage\t1033\n"
227                                         "ProductName\tMSITEST\n"
228                                         "ProductVersion\t1.1.1\n"
229                                         "PROMPTROLLBACKCOST\tP\n"
230                                         "Setup\tSetup\n"
231                                         "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
232                                         "AdminProperties\tPOSTADMIN\n"
233                                         "ROOTDRIVE\tC:\\\n"
234                                         "SERVNAME\tTestService\n"
235                                         "SERVDISP\tTestServiceDisp\n";
236
237 static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
238                                    "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
239                                    "Shortcut\tShortcut\n"
240                                    "Shortcut\tMSITESTDIR\tShortcut\tcomponent\tShortcut\t\tShortcut\t\t\t\t\t\n";
241
242 static const CHAR environment_dat[] = "Environment\tName\tValue\tComponent_\n"
243                                       "s72\tl255\tL255\ts72\n"
244                                       "Environment\tEnvironment\n"
245                                       "Var1\t=-MSITESTVAR1\t1\tOne\n"
246                                       "Var2\tMSITESTVAR2\t1\tOne\n"
247                                       "Var3\t=-MSITESTVAR3\t1\tOne\n"
248                                       "Var4\tMSITESTVAR4\t1\tOne\n"
249                                       "Var5\t-MSITESTVAR5\t\tOne\n"
250                                       "Var6\tMSITESTVAR6\t\tOne\n"
251                                       "Var7\t!-MSITESTVAR7\t\tOne\n"
252                                       "Var8\t!-*MSITESTVAR8\t\tOne\n"
253                                       "Var9\t=-MSITESTVAR9\t\tOne\n"
254                                       "Var10\t=MSITESTVAR10\t\tOne\n"
255                                       "Var11\t+-MSITESTVAR11\t[~];1\tOne\n"
256                                       "Var12\t+-MSITESTVAR11\t[~];2\tOne\n"
257                                       "Var13\t+-MSITESTVAR12\t[~];1\tOne\n"
258                                       "Var14\t=MSITESTVAR13\t[~];1\tOne\n"
259                                       "Var15\t=MSITESTVAR13\t[~];2\tOne\n"
260                                       "Var16\t=MSITESTVAR14\t;1;\tOne\n"
261                                       "Var17\t=MSITESTVAR15\t;;1;;\tOne\n"
262                                       "Var18\t=MSITESTVAR16\t 1 \tOne\n"
263                                       "Var19\t+-MSITESTVAR17\t1\tOne\n"
264                                       "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n"
265                                       "Var21\t+-MSITESTVAR18\t1\tOne\n"
266                                       "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n"
267                                       "Var23\t+-MSITESTVAR19\t1\tOne\n"
268                                       "Var24\t+-MSITESTVAR19\t[~]2\tOne\n"
269                                       "Var25\t+-MSITESTVAR20\t1\tOne\n"
270                                       "Var26\t+-MSITESTVAR20\t2[~]\tOne\n";
271
272 /* Expected results, starting from MSITESTVAR11 onwards */
273 static const CHAR *environment_dat_results[] = {"1;2",    /*MSITESTVAR11*/
274                                                 "1",      /*MSITESTVAR12*/
275                                                 "1;2",    /*MSITESTVAR13*/
276                                                 ";1;",    /*MSITESTVAR14*/
277                                                 ";;1;;",  /*MSITESTVAR15*/
278                                                 " 1 ",    /*MSITESTVAR16*/
279                                                 ";;2;;1", /*MSITESTVAR17*/
280                                                 "1;;2;;", /*MSITESTVAR18*/
281                                                 "1",      /*MSITESTVAR19*/
282                                                 "1",      /*MSITESTVAR20*/
283                                                 NULL};
284
285 static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n"
286                                     "s38\ti2\tS255\n"
287                                     "Condition\tFeature_\tLevel\n"
288                                     "One\t4\t1\n";
289
290 static const CHAR up_property_dat[] = "Property\tValue\n"
291                                       "s72\tl0\n"
292                                       "Property\tProperty\n"
293                                       "DefaultUIFont\tDlgFont8\n"
294                                       "HASUIRUN\t0\n"
295                                       "INSTALLLEVEL\t3\n"
296                                       "InstallMode\tTypical\n"
297                                       "Manufacturer\tWine\n"
298                                       "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
299                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
300                                       "ProductID\tnone\n"
301                                       "ProductLanguage\t1033\n"
302                                       "ProductName\tMSITEST\n"
303                                       "ProductVersion\t1.1.1\n"
304                                       "PROMPTROLLBACKCOST\tP\n"
305                                       "Setup\tSetup\n"
306                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
307                                       "AdminProperties\tPOSTADMIN\n"
308                                       "ROOTDRIVE\tC:\\\n"
309                                       "SERVNAME\tTestService\n"
310                                       "SERVDISP\tTestServiceDisp\n"
311                                       "RemovePreviousVersions\t1\n";
312
313 static const CHAR up2_property_dat[] = "Property\tValue\n"
314                                        "s72\tl0\n"
315                                        "Property\tProperty\n"
316                                        "DefaultUIFont\tDlgFont8\n"
317                                        "HASUIRUN\t0\n"
318                                        "INSTALLLEVEL\t3\n"
319                                        "InstallMode\tTypical\n"
320                                        "Manufacturer\tWine\n"
321                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
322                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
323                                        "ProductID\tnone\n"
324                                        "ProductLanguage\t1033\n"
325                                        "ProductName\tMSITEST\n"
326                                        "ProductVersion\t1.1.2\n"
327                                        "PROMPTROLLBACKCOST\tP\n"
328                                        "Setup\tSetup\n"
329                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
330                                        "AdminProperties\tPOSTADMIN\n"
331                                        "ROOTDRIVE\tC:\\\n"
332                                        "SERVNAME\tTestService\n"
333                                        "SERVDISP\tTestServiceDisp\n";
334
335 static const CHAR up3_property_dat[] = "Property\tValue\n"
336                                        "s72\tl0\n"
337                                        "Property\tProperty\n"
338                                        "DefaultUIFont\tDlgFont8\n"
339                                        "HASUIRUN\t0\n"
340                                        "INSTALLLEVEL\t3\n"
341                                        "InstallMode\tTypical\n"
342                                        "Manufacturer\tWine\n"
343                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
344                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
345                                        "ProductID\tnone\n"
346                                        "ProductLanguage\t1033\n"
347                                        "ProductName\tMSITEST\n"
348                                        "ProductVersion\t1.1.2\n"
349                                        "PROMPTROLLBACKCOST\tP\n"
350                                        "Setup\tSetup\n"
351                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
352                                        "AdminProperties\tPOSTADMIN\n"
353                                        "ROOTDRIVE\tC:\\\n"
354                                        "SERVNAME\tTestService\n"
355                                        "SERVDISP\tTestServiceDisp\n"
356                                        "RemovePreviousVersions\t1\n";
357
358 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
359                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
360                                    "Registry\tRegistry\n"
361                                    "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
362                                    "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
363                                    "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
364                                    "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
365
366 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
367                                           "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
368                                           "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
369                                           "ServiceInstall\tServiceInstall\n"
370                                           "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
371
372 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
373                                           "s72\tl255\ti2\tL255\tI2\ts72\n"
374                                           "ServiceControl\tServiceControl\n"
375                                           "ServiceControl\tTestService\t8\t\t0\tservice_comp";
376
377 static const CHAR sss_service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
378                                               "s72\tl255\ti2\tL255\tI2\ts72\n"
379                                               "ServiceControl\tServiceControl\n"
380                                               "ServiceControl\tSpooler\t1\t\t0\tservice_comp";
381
382 static const CHAR sss_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
383                                                "s72\tS255\tI2\n"
384                                                "InstallExecuteSequence\tAction\n"
385                                                "CostFinalize\t\t1000\n"
386                                                "CostInitialize\t\t800\n"
387                                                "FileCost\t\t900\n"
388                                                "ResolveSource\t\t950\n"
389                                                "MoveFiles\t\t1700\n"
390                                                "InstallFiles\t\t4000\n"
391                                                "DuplicateFiles\t\t4500\n"
392                                                "WriteEnvironmentStrings\t\t4550\n"
393                                                "CreateShortcuts\t\t4600\n"
394                                                "StartServices\t\t5000\n"
395                                                "DeleteServices\t\t5500\n"
396                                                "InstallFinalize\t\t6600\n"
397                                                "InstallInitialize\t\t1500\n"
398                                                "InstallValidate\t\t1400\n"
399                                                "LaunchConditions\t\t100\n";
400
401 /* tables for test_continuouscabs */
402 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
403                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
404                                        "Component\tComponent\n"
405                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
406                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
407                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
408
409 static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
410                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
411                                         "Component\tComponent\n"
412                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
413                                         "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
414                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
415
416 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
417                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
418                                      "Feature\tFeature\n"
419                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
420
421 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
422                                           "s38\ts72\n"
423                                           "FeatureComponents\tFeature_\tComponent_\n"
424                                           "feature\tmaximus\n"
425                                           "feature\taugustus\n"
426                                           "feature\tcaesar";
427
428 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
429                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
430                                   "File\tFile\n"
431                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
432                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
433                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
434
435 static const CHAR cc2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
436                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
437                                    "File\tFile\n"
438                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
439                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
440                                    "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
441                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
442
443 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
444                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
445                                    "Media\tDiskId\n"
446                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
447                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
448                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
449
450 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
451                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
452                                   "File\tFile\n"
453                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
454                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
455                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
456
457 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
458                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
459                                    "Media\tDiskId\n"
460                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
461                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
462                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
463
464 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
465                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
466                                     "Media\tDiskId\n"
467                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
468                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
469                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
470
471 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
472                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
473                                   "File\tFile\n"
474                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
475                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
476                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
477
478 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
479                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
480                                    "Media\tDiskId\n"
481                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
482
483 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
484                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
485                                    "Media\tDiskId\n"
486                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
487                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
488                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
489
490 /* tables for test_uiLevelFlags */
491 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
492                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
493                                        "Component\tComponent\n"
494                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
495                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
496                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
497
498 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
499                                            "s72\tS255\tI2\n"
500                                            "InstallUISequence\tAction\n"
501                                            "SetUIProperty\t\t5\n"
502                                            "ExecuteAction\t\t1100\n";
503
504 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
505                                            "s72\ti2\tS64\tS0\tS255\n"
506                                            "CustomAction\tAction\n"
507                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
508
509 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
510                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
511                                         "Component\tComponent\n"
512                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
513
514 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
515                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
516                                       "Feature\tFeature\n"
517                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
518                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
519
520 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
521                                            "s38\ts72\n"
522                                            "FeatureComponents\tFeature_\tComponent_\n"
523                                            "feature\tmaximus\n"
524                                            "montecristo\tmaximus";
525
526 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
527                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
528                                    "File\tFile\n"
529                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
530
531 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
532                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
533                                     "Media\tDiskId\n"
534                                     "1\t1\t\t\tDISK1\t\n";
535
536 static const CHAR rofc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
537                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
538                                     "File\tFile\n"
539                                     "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1";
540
541 static const CHAR rofc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
542                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
543                                      "Media\tDiskId\n"
544                                      "1\t1\t\ttest1.cab\tDISK1\t\n";
545
546 static const CHAR lus2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
547                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
548                                      "Media\tDiskId\n"
549                                      "1\t1\t\t#test1.cab\tDISK1\t\n";
550
551 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
552                                                "s72\tS255\tI2\n"
553                                                "InstallExecuteSequence\tAction\n"
554                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
555                                                "CostFinalize\t\t1000\n"
556                                                "CostInitialize\t\t800\n"
557                                                "FileCost\t\t900\n"
558                                                "InstallFiles\t\t4000\n"
559                                                "InstallFinalize\t\t6600\n"
560                                                "InstallInitialize\t\t1500\n"
561                                                "InstallValidate\t\t1400\n"
562                                                "LaunchConditions\t\t100\n"
563                                                "SetDirProperty\t\t950";
564
565 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
566                                             "s72\ti2\tS64\tS0\tS255\n"
567                                             "CustomAction\tAction\n"
568                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
569
570 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
571                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
572                                         "Component\tComponent\n"
573                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
574                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
575                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
576                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
577
578 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
579                                            "s38\ts72\n"
580                                            "FeatureComponents\tFeature_\tComponent_\n"
581                                            "feature\tmaximus\n"
582                                            "feature\taugustus\n"
583                                            "feature\tcaesar\n"
584                                            "feature\tgaius";
585
586 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
587                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
588                                    "File\tFile\n"
589                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
590                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
591                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
592                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
593
594 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
595                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
596                                     "Media\tDiskId\n"
597                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
598                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
599                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
600
601 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
602                                               "s72\tS255\tI2\n"
603                                               "InstallExecuteSequence\tAction\n"
604                                               "CostFinalize\t\t1000\n"
605                                               "CostInitialize\t\t800\n"
606                                               "FileCost\t\t900\n"
607                                               "InstallFiles\t\t4000\n"
608                                               "InstallServices\t\t5000\n"
609                                               "InstallFinalize\t\t6600\n"
610                                               "InstallInitialize\t\t1500\n"
611                                               "RunInstall\t\t1600\n"
612                                               "InstallValidate\t\t1400\n"
613                                               "LaunchConditions\t\t100";
614
615 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
616                                             "s72\ti2\tS64\tS0\tS255\n"
617                                             "CustomAction\tAction\n"
618                                             "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
619
620 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
621                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
622                                        "Component\tComponent\n"
623                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
624
625 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
626                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
627                                         "Component\tComponent\n"
628                                         "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
629
630 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
631                                            "s38\ts72\n"
632                                            "FeatureComponents\tFeature_\tComponent_\n"
633                                            "feature\taugustus";
634
635 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
636                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
637                                    "File\tFile\n"
638                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
639
640 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
641                                             "s72\ti2\tS64\tS0\tS255\n"
642                                             "CustomAction\tAction\n"
643                                             "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
644
645 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
646                                                "s72\tS255\tI2\n"
647                                                "InstallExecuteSequence\tAction\n"
648                                                "CostFinalize\t\t1000\n"
649                                                "CostInitialize\t\t800\n"
650                                                "FileCost\t\t900\n"
651                                                "SetFolderProp\t\t950\n"
652                                                "InstallFiles\t\t4000\n"
653                                                "InstallServices\t\t5000\n"
654                                                "InstallFinalize\t\t6600\n"
655                                                "InstallInitialize\t\t1500\n"
656                                                "InstallValidate\t\t1400\n"
657                                                "LaunchConditions\t\t100";
658
659 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
660                                              "s72\tS255\tI2\n"
661                                              "InstallUISequence\tAction\n"
662                                              "CostInitialize\t\t800\n"
663                                              "FileCost\t\t900\n"
664                                              "CostFinalize\t\t1000\n"
665                                              "ExecuteAction\t\t1100\n";
666
667 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
668                                               "s72\tS255\tI2\n"
669                                               "InstallExecuteSequence\tAction\n"
670                                               "ValidateProductID\t\t700\n"
671                                               "CostInitialize\t\t800\n"
672                                               "FileCost\t\t900\n"
673                                               "CostFinalize\t\t1000\n"
674                                               "InstallValidate\t\t1400\n"
675                                               "InstallInitialize\t\t1500\n"
676                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
677                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
678                                               "RemoveFiles\t\t3500\n"
679                                               "InstallFiles\t\t4000\n"
680                                               "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
681                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
682                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
683                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
684                                               "InstallFinalize\t\t6600";
685
686 static const CHAR ppc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
687                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
688                                         "Component\tComponent\n"
689                                         "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n"
690                                         "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n";
691
692 static const CHAR ppc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
693                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
694                                    "File\tFile\n"
695                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n"
696                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t2";
697
698 static const CHAR ppc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
699                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
700                                     "Media\tDiskId\n"
701                                     "1\t2\t\t\tDISK1\t\n";
702
703 static const CHAR ppc_feature_comp_dat[] = "Feature_\tComponent_\n"
704                                            "s38\ts72\n"
705                                            "FeatureComponents\tFeature_\tComponent_\n"
706                                            "feature\tmaximus\n"
707                                            "feature\taugustus\n"
708                                            "montecristo\tmaximus";
709
710 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
711                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
712                                        "Component\tComponent\n"
713                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
714
715 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
716                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
717                                         "Component\tComponent\n"
718                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
719
720 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
721                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
722                                         "Component\tComponent\n"
723                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
724
725 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
726                                             "s72\ti2\tS64\tS0\tS255\n"
727                                             "CustomAction\tAction\n"
728                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
729
730 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
731                                              "s72\tS255\tI2\n"
732                                              "AdminExecuteSequence\tAction\n"
733                                              "CostFinalize\t\t1000\n"
734                                              "CostInitialize\t\t800\n"
735                                              "FileCost\t\t900\n"
736                                              "SetPOSTADMIN\t\t950\n"
737                                              "InstallFiles\t\t4000\n"
738                                              "InstallFinalize\t\t6600\n"
739                                              "InstallInitialize\t\t1500\n"
740                                              "InstallValidate\t\t1400\n"
741                                              "LaunchConditions\t\t100";
742
743 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
744                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
745                                         "Component\tComponent\n"
746                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718 and MyProp=42\taugustus\n";
747
748 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
749                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
750                                         "Component\tComponent\n"
751                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
752                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
753                                         "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
754
755 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
756                                            "s38\ts72\n"
757                                            "FeatureComponents\tFeature_\tComponent_\n"
758                                            "feature\thydrogen\n"
759                                            "feature\thelium\n"
760                                            "feature\tlithium";
761
762 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
763                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
764                                    "File\tFile\n"
765                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
766                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
767                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
768
769 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
770                                                "s72\tS255\tI2\n"
771                                                "InstallExecuteSequence\tAction\n"
772                                                "ValidateProductID\t\t700\n"
773                                                "CostInitialize\t\t800\n"
774                                                "FileCost\t\t900\n"
775                                                "CostFinalize\t\t1000\n"
776                                                "InstallValidate\t\t1400\n"
777                                                "InstallInitialize\t\t1500\n"
778                                                "ProcessComponents\t\t1600\n"
779                                                "UnpublishFeatures\t\t1800\n"
780                                                "RemoveFiles\t\t3500\n"
781                                                "InstallFiles\t\t4000\n"
782                                                "RegisterProduct\t\t6100\n"
783                                                "PublishFeatures\t\t6300\n"
784                                                "PublishProduct\t\t6400\n"
785                                                "InstallFinalize\t\t6600";
786
787 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
788                                            "s72\ts72\tS255\ts72\tI2\n"
789                                            "RemoveFile\tFileKey\n"
790                                            "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
791                                            "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
792                                            "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
793                                            "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
794                                            "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
795                                            "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
796                                            "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
797                                            "block\thelium\tblock\tMSITESTDIR\t3\n"
798                                            "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n"
799                                            "nanoacre\thydrogen\t\tCABOUTDIR\t3\n";
800
801 static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
802                                         "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
803                                         "MoveFile\tFileKey\n"
804                                         "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
805                                         "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
806                                         "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
807                                         "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
808                                         "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
809                                         "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
810                                         "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
811                                         "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
812                                         "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
813                                         "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
814                                         "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
815                                         "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
816                                         "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
817                                         "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n"
818                                         "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
819                                         "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
820                                         "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
821                                         "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
822
823 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
824                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
825                                         "Component\tComponent\n"
826                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
827                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
828                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
829                                         "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
830
831 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
832                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
833                                   "File\tFile\n"
834                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
835                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
836                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
837                                   "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
838
839 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
840                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
841                                    "Media\tDiskId\n"
842                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
843                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
844                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
845                                    "4\t4\t\ttest3.cab\tDISK3\t\n";
846
847 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
848                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
849                                        "MsiFileHash\tFile_\n"
850                                        "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
851
852 static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
853                                        "s72\tS72\tl255\n"
854                                        "Directory\tDirectory\n"
855                                        "THIS\tMSITESTDIR\tthis\n"
856                                        "DOESNOT\tTHIS\tdoesnot\n"
857                                        "NONEXISTENT\tDOESNOT\texist\n"
858                                        "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
859                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
860                                        "TARGETDIR\t\tSourceDir";
861
862 static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
863                                             "s72\ts72\ts72\tS255\tS72\n"
864                                             "DuplicateFile\tFileKey\n"
865                                             "maximus\tmaximus\tmaximus\taugustus\t\n"
866                                             "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n"
867                                             "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n";
868
869 static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
870                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
871                                         "Component\tComponent\n"
872                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
873
874 static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
875                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
876                                        "Registry\tRegistry\n"
877                                        "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
878
879 static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
880                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
881                                          "Component\tComponent\n"
882                                          "augustus\t\tMSITESTDIR\t0\tMYPROP=42\taugustus\n";
883
884 static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
885                                                 "s72\tS255\tI2\n"
886                                                 "InstallExecuteSequence\tAction\n"
887                                                 "ValidateProductID\t\t700\n"
888                                                 "GoodSetProperty\t\t725\n"
889                                                 "BadSetProperty\t\t750\n"
890                                                 "CostInitialize\t\t800\n"
891                                                 "ResolveSource\t\t810\n"
892                                                 "FileCost\t\t900\n"
893                                                 "SetSourceDir\tSRCDIR\t910\n"
894                                                 "CostFinalize\t\t1000\n"
895                                                 "InstallValidate\t\t1400\n"
896                                                 "InstallInitialize\t\t1500\n"
897                                                 "InstallFiles\t\t4000\n"
898                                                 "InstallFinalize\t\t6600";
899
900 static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
901                                              "s72\ti2\tS64\tS0\n"
902                                              "CustomAction\tAction\n"
903                                              "GoodSetProperty\t51\tMYPROP\t42\n"
904                                              "BadSetProperty\t51\t\tMYPROP\n"
905                                              "SetSourceDir\t51\tSourceDir\t[SRCDIR]\n";
906
907 static const CHAR is_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
908                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
909                                      "Feature\tFeature\n"
910                                      "one\t\t\t\t2\t1\t\t0\n" /* favorLocal */
911                                      "two\t\t\t\t2\t1\t\t1\n" /* favorSource */
912                                      "three\t\t\t\t2\t1\t\t4\n" /* favorAdvertise */
913                                      "four\t\t\t\t2\t0\t\t0"; /* disabled */
914
915 static const CHAR is_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
916                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
917                                        "Component\tComponent\n"
918                                        "alpha\t\tMSITESTDIR\t0\t\talpha_file\n" /* favorLocal:Local */
919                                        "beta\t\tMSITESTDIR\t1\t\tbeta_file\n" /* favorLocal:Source */
920                                        "gamma\t\tMSITESTDIR\t2\t\tgamma_file\n" /* favorLocal:Optional */
921                                        "theta\t\tMSITESTDIR\t0\t\ttheta_file\n" /* favorSource:Local */
922                                        "delta\t\tMSITESTDIR\t1\t\tdelta_file\n" /* favorSource:Source */
923                                        "epsilon\t\tMSITESTDIR\t2\t\tepsilon_file\n" /* favorSource:Optional */
924                                        "zeta\t\tMSITESTDIR\t0\t\tzeta_file\n" /* favorAdvertise:Local */
925                                        "iota\t\tMSITESTDIR\t1\t\tiota_file\n" /* favorAdvertise:Source */
926                                        "eta\t\tMSITESTDIR\t2\t\teta_file\n" /* favorAdvertise:Optional */
927                                        "kappa\t\tMSITESTDIR\t0\t\tkappa_file\n" /* disabled:Local */
928                                        "lambda\t\tMSITESTDIR\t1\t\tlambda_file\n" /* disabled:Source */
929                                        "mu\t\tMSITESTDIR\t2\t\tmu_file\n"; /* disabled:Optional */
930
931 static const CHAR is_feature_comp_dat[] = "Feature_\tComponent_\n"
932                                           "s38\ts72\n"
933                                           "FeatureComponents\tFeature_\tComponent_\n"
934                                           "one\talpha\n"
935                                           "one\tbeta\n"
936                                           "one\tgamma\n"
937                                           "two\ttheta\n"
938                                           "two\tdelta\n"
939                                           "two\tepsilon\n"
940                                           "three\tzeta\n"
941                                           "three\tiota\n"
942                                           "three\teta\n"
943                                           "four\tkappa\n"
944                                           "four\tlambda\n"
945                                           "four\tmu";
946
947 static const CHAR is_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
948                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
949                                   "File\tFile\n"
950                                   "alpha_file\talpha\talpha\t500\t\t\t8192\t1\n"
951                                   "beta_file\tbeta\tbeta\t500\t\t\t8291\t2\n"
952                                   "gamma_file\tgamma\tgamma\t500\t\t\t8192\t3\n"
953                                   "theta_file\ttheta\ttheta\t500\t\t\t8192\t4\n"
954                                   "delta_file\tdelta\tdelta\t500\t\t\t8192\t5\n"
955                                   "epsilon_file\tepsilon\tepsilon\t500\t\t\t8192\t6\n"
956                                   "zeta_file\tzeta\tzeta\t500\t\t\t8192\t7\n"
957                                   "iota_file\tiota\tiota\t500\t\t\t8192\t8\n"
958                                   "eta_file\teta\teta\t500\t\t\t8192\t9\n"
959                                   "kappa_file\tkappa\tkappa\t500\t\t\t8192\t10\n"
960                                   "lambda_file\tlambda\tlambda\t500\t\t\t8192\t11\n"
961                                   "mu_file\tmu\tmu\t500\t\t\t8192\t12";
962
963 static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
964                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
965                                    "Media\tDiskId\n"
966                                    "1\t12\t\t\tDISK1\t\n";
967
968 static const CHAR sp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
969                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
970                                         "Component\tComponent\n"
971                                         "augustus\t\tTWODIR\t0\t\taugustus\n";
972
973 static const CHAR sp_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
974                                        "s72\tS72\tl255\n"
975                                        "Directory\tDirectory\n"
976                                        "TARGETDIR\t\tSourceDir\n"
977                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
978                                        "MSITESTDIR\tProgramFilesFolder\tmsitest:.\n"
979                                        "ONEDIR\tMSITESTDIR\t.:shortone|longone\n"
980                                        "TWODIR\tONEDIR\t.:shorttwo|longtwo";
981
982 static const CHAR mcp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
983                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
984                                         "Component\tComponent\n"
985                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
986                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
987                                         "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
988
989 static const CHAR mcp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
990                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
991                                       "Feature\tFeature\n"
992                                       "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
993                                       "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
994                                       "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
995
996 static const CHAR mcp_feature_comp_dat[] = "Feature_\tComponent_\n"
997                                            "s38\ts72\n"
998                                            "FeatureComponents\tFeature_\tComponent_\n"
999                                            "hydroxyl\thydrogen\n"
1000                                            "heliox\thelium\n"
1001                                            "lithia\tlithium";
1002
1003 static const CHAR mcomp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1004                                      "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1005                                      "File\tFile\n"
1006                                      "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
1007                                      "helium\thelium\thelium\t0\t\t\t8192\t1\n"
1008                                      "lithium\tlithium\tlithium\t0\t\t\t8192\t1\n"
1009                                      "beryllium\tmissingcomp\tberyllium\t0\t\t\t8192\t1";
1010
1011 static const CHAR ai_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1012                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1013                                   "File\tFile\n"
1014                                   "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
1015                                   "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
1016                                   "one.txt\tOne\tone.txt\t1000\t\t\t16384\t1\n"
1017                                   "three.txt\tThree\tthree.txt\t1000\t\t\t16384\t3\n"
1018                                   "two.txt\tTwo\ttwo.txt\t1000\t\t\t16384\t2\n"
1019                                   "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
1020                                   "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
1021
1022 static const CHAR ip_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1023                                               "s72\tS255\tI2\n"
1024                                               "InstallExecuteSequence\tAction\n"
1025                                               "CostFinalize\t\t1000\n"
1026                                               "ValidateProductID\t\t700\n"
1027                                               "CostInitialize\t\t800\n"
1028                                               "FileCost\t\t900\n"
1029                                               "RemoveFiles\t\t3500\n"
1030                                               "InstallFiles\t\t4000\n"
1031                                               "RegisterUser\t\t6000\n"
1032                                               "RegisterProduct\t\t6100\n"
1033                                               "PublishFeatures\t\t6300\n"
1034                                               "PublishProduct\t\t6400\n"
1035                                               "InstallFinalize\t\t6600\n"
1036                                               "InstallInitialize\t\t1500\n"
1037                                               "ProcessComponents\t\t1600\n"
1038                                               "UnpublishFeatures\t\t1800\n"
1039                                               "InstallValidate\t\t1400\n"
1040                                               "LaunchConditions\t\t100\n"
1041                                               "TestInstalledProp\tInstalled AND NOT REMOVE\t950\n";
1042
1043 static const CHAR ip_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1044                                            "s72\ti2\tS64\tS0\tS255\n"
1045                                            "CustomAction\tAction\n"
1046                                            "TestInstalledProp\t19\t\tTest failed\t\n";
1047
1048 static const CHAR aup_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1049                                                "s72\tS255\tI2\n"
1050                                                "InstallExecuteSequence\tAction\n"
1051                                                "CostFinalize\t\t1000\n"
1052                                                "ValidateProductID\t\t700\n"
1053                                                "CostInitialize\t\t800\n"
1054                                                "FileCost\t\t900\n"
1055                                                "RemoveFiles\t\t3500\n"
1056                                                "InstallFiles\t\t4000\n"
1057                                                "RegisterUser\t\t6000\n"
1058                                                "RegisterProduct\t\t6100\n"
1059                                                "PublishFeatures\t\t6300\n"
1060                                                "PublishProduct\t\t6400\n"
1061                                                "InstallFinalize\t\t6600\n"
1062                                                "InstallInitialize\t\t1500\n"
1063                                                "ProcessComponents\t\t1600\n"
1064                                                "UnpublishFeatures\t\t1800\n"
1065                                                "InstallValidate\t\t1400\n"
1066                                                "LaunchConditions\t\t100\n"
1067                                                "TestAllUsersProp\tALLUSERS AND NOT REMOVE\t50\n";
1068
1069 static const CHAR aup2_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1070                                                 "s72\tS255\tI2\n"
1071                                                 "InstallExecuteSequence\tAction\n"
1072                                                 "CostFinalize\t\t1000\n"
1073                                                 "ValidateProductID\t\t700\n"
1074                                                 "CostInitialize\t\t800\n"
1075                                                 "FileCost\t\t900\n"
1076                                                 "RemoveFiles\t\t3500\n"
1077                                                 "InstallFiles\t\t4000\n"
1078                                                 "RegisterUser\t\t6000\n"
1079                                                 "RegisterProduct\t\t6100\n"
1080                                                 "PublishFeatures\t\t6300\n"
1081                                                 "PublishProduct\t\t6400\n"
1082                                                 "InstallFinalize\t\t6600\n"
1083                                                 "InstallInitialize\t\t1500\n"
1084                                                 "ProcessComponents\t\t1600\n"
1085                                                 "UnpublishFeatures\t\t1800\n"
1086                                                 "InstallValidate\t\t1400\n"
1087                                                 "LaunchConditions\t\t100\n"
1088                                                 "TestAllUsersProp\tALLUSERS=2 AND NOT REMOVE\t50\n";
1089
1090 static const CHAR aup3_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1091                                                 "s72\tS255\tI2\n"
1092                                                 "InstallExecuteSequence\tAction\n"
1093                                                 "CostFinalize\t\t1000\n"
1094                                                 "ValidateProductID\t\t700\n"
1095                                                 "CostInitialize\t\t800\n"
1096                                                 "FileCost\t\t900\n"
1097                                                 "RemoveFiles\t\t3500\n"
1098                                                 "InstallFiles\t\t4000\n"
1099                                                 "RegisterUser\t\t6000\n"
1100                                                 "RegisterProduct\t\t6100\n"
1101                                                 "PublishFeatures\t\t6300\n"
1102                                                 "PublishProduct\t\t6400\n"
1103                                                 "InstallFinalize\t\t6600\n"
1104                                                 "InstallInitialize\t\t1500\n"
1105                                                 "ProcessComponents\t\t1600\n"
1106                                                 "UnpublishFeatures\t\t1800\n"
1107                                                 "InstallValidate\t\t1400\n"
1108                                                 "LaunchConditions\t\t100\n"
1109                                                 "TestAllUsersProp\tALLUSERS=1 AND NOT REMOVE\t50\n";
1110
1111 static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1112                                             "s72\ti2\tS64\tS0\tS255\n"
1113                                             "CustomAction\tAction\n"
1114                                             "TestAllUsersProp\t19\t\tTest failed\t\n";
1115
1116 static const CHAR cf_create_folders_dat[] = "Directory_\tComponent_\n"
1117                                             "s72\ts72\n"
1118                                             "CreateFolder\tDirectory_\tComponent_\n"
1119                                             "FIRSTDIR\tOne\n";
1120
1121 static const CHAR cf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1122                                               "s72\tS255\tI2\n"
1123                                               "InstallExecuteSequence\tAction\n"
1124                                               "CostFinalize\t\t1000\n"
1125                                               "ValidateProductID\t\t700\n"
1126                                               "CostInitialize\t\t800\n"
1127                                               "FileCost\t\t900\n"
1128                                               "RemoveFiles\t\t3500\n"
1129                                               "CreateFolders\t\t3700\n"
1130                                               "InstallExecute\t\t3800\n"
1131                                               "TestCreateFolders\t\t3900\n"
1132                                               "InstallFiles\t\t4000\n"
1133                                               "RegisterUser\t\t6000\n"
1134                                               "RegisterProduct\t\t6100\n"
1135                                               "PublishFeatures\t\t6300\n"
1136                                               "PublishProduct\t\t6400\n"
1137                                               "InstallFinalize\t\t6600\n"
1138                                               "InstallInitialize\t\t1500\n"
1139                                               "ProcessComponents\t\t1600\n"
1140                                               "UnpublishFeatures\t\t1800\n"
1141                                               "InstallValidate\t\t1400\n"
1142                                               "LaunchConditions\t\t100\n";
1143
1144 static const CHAR cf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1145                                            "s72\ti2\tS64\tS0\tS255\n"
1146                                            "CustomAction\tAction\n"
1147                                            "TestCreateFolders\t19\t\tHalts installation\t\n";
1148
1149 static const CHAR rf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1150                                               "s72\tS255\tI2\n"
1151                                               "InstallExecuteSequence\tAction\n"
1152                                               "CostFinalize\t\t1000\n"
1153                                               "ValidateProductID\t\t700\n"
1154                                               "CostInitialize\t\t800\n"
1155                                               "FileCost\t\t900\n"
1156                                               "RemoveFiles\t\t3500\n"
1157                                               "CreateFolders\t\t3600\n"
1158                                               "RemoveFolders\t\t3700\n"
1159                                               "InstallExecute\t\t3800\n"
1160                                               "TestCreateFolders\t\t3900\n"
1161                                               "InstallFiles\t\t4000\n"
1162                                               "RegisterUser\t\t6000\n"
1163                                               "RegisterProduct\t\t6100\n"
1164                                               "PublishFeatures\t\t6300\n"
1165                                               "PublishProduct\t\t6400\n"
1166                                               "InstallFinalize\t\t6600\n"
1167                                               "InstallInitialize\t\t1500\n"
1168                                               "ProcessComponents\t\t1600\n"
1169                                               "UnpublishFeatures\t\t1800\n"
1170                                               "InstallValidate\t\t1400\n"
1171                                               "LaunchConditions\t\t100\n";
1172
1173
1174 static const CHAR sr_selfreg_dat[] = "File_\tCost\n"
1175                                      "s72\tI2\n"
1176                                      "SelfReg\tFile_\n"
1177                                      "one.txt\t1\n";
1178
1179 static const CHAR sr_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1180                                               "s72\tS255\tI2\n"
1181                                               "InstallExecuteSequence\tAction\n"
1182                                               "CostFinalize\t\t1000\n"
1183                                               "CostInitialize\t\t800\n"
1184                                               "FileCost\t\t900\n"
1185                                               "ResolveSource\t\t950\n"
1186                                               "MoveFiles\t\t1700\n"
1187                                               "SelfUnregModules\t\t3900\n"
1188                                               "InstallFiles\t\t4000\n"
1189                                               "DuplicateFiles\t\t4500\n"
1190                                               "WriteEnvironmentStrings\t\t4550\n"
1191                                               "CreateShortcuts\t\t4600\n"
1192                                               "InstallFinalize\t\t6600\n"
1193                                               "InstallInitialize\t\t1500\n"
1194                                               "InstallValidate\t\t1400\n"
1195                                               "LaunchConditions\t\t100\n";
1196
1197 static const CHAR font_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
1198                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
1199                                      "Media\tDiskId\n"
1200                                      "1\t3\t\t\tDISK1\t\n";
1201
1202 static const CHAR font_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1203                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1204                                     "File\tFile\n"
1205                                     "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n";
1206
1207 static const CHAR font_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1208                                        "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1209                                        "Feature\tFeature\n"
1210                                        "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n";
1211
1212 static const CHAR font_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1213                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
1214                                          "Component\tComponent\n"
1215                                          "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n";
1216
1217 static const CHAR font_feature_comp_dat[] = "Feature_\tComponent_\n"
1218                                             "s38\ts72\n"
1219                                             "FeatureComponents\tFeature_\tComponent_\n"
1220                                             "fonts\tfonts\n";
1221
1222 static const CHAR font_dat[] = "File_\tFontTitle\n"
1223                                "s72\tS128\n"
1224                                "Font\tFile_\n"
1225                                "font.ttf\tmsi test font\n";
1226
1227 static const CHAR font_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1228                                                 "s72\tS255\tI2\n"
1229                                                 "InstallExecuteSequence\tAction\n"
1230                                                 "ValidateProductID\t\t700\n"
1231                                                 "CostInitialize\t\t800\n"
1232                                                 "FileCost\t\t900\n"
1233                                                 "CostFinalize\t\t1000\n"
1234                                                 "InstallValidate\t\t1400\n"
1235                                                 "InstallInitialize\t\t1500\n"
1236                                                 "ProcessComponents\t\t1600\n"
1237                                                 "UnpublishFeatures\t\t1800\n"
1238                                                 "RemoveFiles\t\t3500\n"
1239                                                 "InstallFiles\t\t4000\n"
1240                                                 "RegisterFonts\t\t4100\n"
1241                                                 "UnregisterFonts\t\t4200\n"
1242                                                 "RegisterUser\t\t6000\n"
1243                                                 "RegisterProduct\t\t6100\n"
1244                                                 "PublishFeatures\t\t6300\n"
1245                                                 "PublishProduct\t\t6400\n"
1246                                                 "InstallFinalize\t\t6600";
1247
1248 static const CHAR vp_property_dat[] = "Property\tValue\n"
1249                                       "s72\tl0\n"
1250                                       "Property\tProperty\n"
1251                                       "HASUIRUN\t0\n"
1252                                       "INSTALLLEVEL\t3\n"
1253                                       "InstallMode\tTypical\n"
1254                                       "Manufacturer\tWine\n"
1255                                       "PIDTemplate\t###-#######\n"
1256                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
1257                                       "ProductLanguage\t1033\n"
1258                                       "ProductName\tMSITEST\n"
1259                                       "ProductVersion\t1.1.1\n"
1260                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n";
1261
1262 static const CHAR vp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1263                                            "s72\ti2\tS64\tS0\tS255\n"
1264                                            "CustomAction\tAction\n"
1265                                            "SetProductID1\t51\tProductID\t1\t\n"
1266                                            "SetProductID2\t51\tProductID\t2\t\n"
1267                                            "TestProductID1\t19\t\t\tHalts installation\n"
1268                                            "TestProductID2\t19\t\t\tHalts installation\n";
1269
1270 static const CHAR vp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1271                                               "s72\tS255\tI2\n"
1272                                               "InstallExecuteSequence\tAction\n"
1273                                               "LaunchConditions\t\t100\n"
1274                                               "CostInitialize\t\t800\n"
1275                                               "FileCost\t\t900\n"
1276                                               "CostFinalize\t\t1000\n"
1277                                               "InstallValidate\t\t1400\n"
1278                                               "InstallInitialize\t\t1500\n"
1279                                               "SetProductID1\tSET_PRODUCT_ID=1\t3000\n"
1280                                               "SetProductID2\tSET_PRODUCT_ID=2\t3100\n"
1281                                               "ValidateProductID\t\t3200\n"
1282                                               "InstallExecute\t\t3300\n"
1283                                               "TestProductID1\tProductID=1\t3400\n"
1284                                               "TestProductID2\tProductID=\"123-1234567\"\t3500\n"
1285                                               "InstallFiles\t\t4000\n"
1286                                               "InstallFinalize\t\t6000\n";
1287
1288 static const CHAR odbc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1289                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1290                                     "File\tFile\n"
1291                                     "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n"
1292                                     "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n"
1293                                     "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n"
1294                                     "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n"
1295                                     "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n";
1296
1297 static const CHAR odbc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1298                                        "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1299                                        "Feature\tFeature\n"
1300                                        "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n";
1301
1302 static const CHAR odbc_feature_comp_dat[] = "Feature_\tComponent_\n"
1303                                             "s38\ts72\n"
1304                                             "FeatureComponents\tFeature_\tComponent_\n"
1305                                             "odbc\todbc\n";
1306
1307 static const CHAR odbc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1308                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
1309                                          "Component\tComponent\n"
1310                                          "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n";
1311
1312 static const CHAR odbc_driver_dat[] = "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n"
1313                                       "s72\ts72\ts255\ts72\tS72\n"
1314                                       "ODBCDriver\tDriver\n"
1315                                       "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n"
1316                                       "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n";
1317
1318 static const CHAR odbc_translator_dat[] = "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n"
1319                                           "s72\ts72\ts255\ts72\tS72\n"
1320                                           "ODBCTranslator\tTranslator\n"
1321                                           "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n"
1322                                           "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n";
1323
1324 static const CHAR odbc_datasource_dat[] = "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n"
1325                                           "s72\ts72\ts255\ts255\ti2\n"
1326                                           "ODBCDataSource\tDataSource\n"
1327                                           "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n";
1328
1329 static const CHAR odbc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1330                                                 "s72\tS255\tI2\n"
1331                                                 "InstallExecuteSequence\tAction\n"
1332                                                 "LaunchConditions\t\t100\n"
1333                                                 "CostInitialize\t\t800\n"
1334                                                 "FileCost\t\t900\n"
1335                                                 "CostFinalize\t\t1000\n"
1336                                                 "InstallValidate\t\t1400\n"
1337                                                 "InstallInitialize\t\t1500\n"
1338                                                 "ProcessComponents\t\t1600\n"
1339                                                 "InstallODBC\t\t3000\n"
1340                                                 "RemoveODBC\t\t3100\n"
1341                                                 "RemoveFiles\t\t3900\n"
1342                                                 "InstallFiles\t\t4000\n"
1343                                                 "RegisterProduct\t\t5000\n"
1344                                                 "PublishFeatures\t\t5100\n"
1345                                                 "PublishProduct\t\t5200\n"
1346                                                 "InstallFinalize\t\t6000\n";
1347
1348 static const CHAR odbc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
1349                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
1350                                      "Media\tDiskId\n"
1351                                      "1\t5\t\t\tDISK1\t\n";
1352
1353 static const CHAR tl_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1354                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1355                                   "File\tFile\n"
1356                                   "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
1357
1358 static const CHAR tl_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1359                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1360                                      "Feature\tFeature\n"
1361                                      "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
1362
1363 static const CHAR tl_feature_comp_dat[] = "Feature_\tComponent_\n"
1364                                           "s38\ts72\n"
1365                                           "FeatureComponents\tFeature_\tComponent_\n"
1366                                           "typelib\ttypelib\n";
1367
1368 static const CHAR tl_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1369                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1370                                        "Component\tComponent\n"
1371                                        "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
1372
1373 static const CHAR tl_typelib_dat[] = "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
1374                                      "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
1375                                      "TypeLib\tLibID\tLanguage\tComponent_\n"
1376                                      "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
1377
1378 static const CHAR tl_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1379                                               "s72\tS255\tI2\n"
1380                                               "InstallExecuteSequence\tAction\n"
1381                                               "LaunchConditions\t\t100\n"
1382                                               "CostInitialize\t\t800\n"
1383                                               "FileCost\t\t900\n"
1384                                               "CostFinalize\t\t1000\n"
1385                                               "InstallValidate\t\t1400\n"
1386                                               "InstallInitialize\t\t1500\n"
1387                                               "ProcessComponents\t\t1600\n"
1388                                               "RemoveFiles\t\t1700\n"
1389                                               "InstallFiles\t\t2000\n"
1390                                               "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
1391                                               "UnregisterTypeLibraries\t\t3100\n"
1392                                               "RegisterProduct\t\t5100\n"
1393                                               "PublishFeatures\t\t5200\n"
1394                                               "PublishProduct\t\t5300\n"
1395                                               "InstallFinalize\t\t6000\n";
1396
1397 static const CHAR crs_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1398                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1399                                    "File\tFile\n"
1400                                    "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n";
1401
1402 static const CHAR crs_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1403                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1404                                       "Feature\tFeature\n"
1405                                       "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n";
1406
1407 static const CHAR crs_feature_comp_dat[] = "Feature_\tComponent_\n"
1408                                            "s38\ts72\n"
1409                                            "FeatureComponents\tFeature_\tComponent_\n"
1410                                            "shortcut\tshortcut\n";
1411
1412 static const CHAR crs_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1413                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1414                                         "Component\tComponent\n"
1415                                         "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n";
1416
1417 static const CHAR crs_shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
1418                                        "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n"
1419                                        "Shortcut\tShortcut\n"
1420                                        "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n";
1421
1422 static const CHAR crs_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1423                                                "s72\tS255\tI2\n"
1424                                                "InstallExecuteSequence\tAction\n"
1425                                                "LaunchConditions\t\t100\n"
1426                                                "CostInitialize\t\t800\n"
1427                                                "FileCost\t\t900\n"
1428                                                "CostFinalize\t\t1000\n"
1429                                                "InstallValidate\t\t1400\n"
1430                                                "InstallInitialize\t\t1500\n"
1431                                                "ProcessComponents\t\t1600\n"
1432                                                "RemoveFiles\t\t1700\n"
1433                                                "InstallFiles\t\t2000\n"
1434                                                "RemoveShortcuts\t\t3000\n"
1435                                                "CreateShortcuts\t\t3100\n"
1436                                                "RegisterProduct\t\t5000\n"
1437                                                "PublishFeatures\t\t5100\n"
1438                                                "PublishProduct\t\t5200\n"
1439                                                "InstallFinalize\t\t6000\n";
1440
1441 static const CHAR fo_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1442                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1443                                   "File\tFile\n"
1444                                   "override.txt\toverride\toverride.txt\t1000\t\t\t8192\t1\n"
1445                                   "preselected.txt\tpreselected\tpreselected.txt\t1000\t\t\t8192\t2\n"
1446                                   "notpreselected.txt\tnotpreselected\tnotpreselected.txt\t1000\t\t\t8192\t3\n";
1447
1448 static const CHAR fo_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1449                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1450                                      "Feature\tFeature\n"
1451                                      "override\t\t\toverride feature\t1\t1\tMSITESTDIR\t0\n"
1452                                      "preselected\t\t\tpreselected feature\t1\t1\tMSITESTDIR\t0\n"
1453                                      "notpreselected\t\t\tnotpreselected feature\t1\t1\tMSITESTDIR\t0\n";
1454
1455 static const CHAR fo_condition_dat[] = "Feature_\tLevel\tCondition\n"
1456                                        "s38\ti2\tS255\n"
1457                                        "Condition\tFeature_\tLevel\n"
1458                                        "preselected\t0\tPreselected\n"
1459                                        "notpreselected\t0\tNOT Preselected\n";
1460
1461 static const CHAR fo_feature_comp_dat[] = "Feature_\tComponent_\n"
1462                                           "s38\ts72\n"
1463                                           "FeatureComponents\tFeature_\tComponent_\n"
1464                                           "override\toverride\n"
1465                                           "preselected\tpreselected\n"
1466                                           "notpreselected\tnotpreselected\n";
1467
1468 static const CHAR fo_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1469                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1470                                        "Component\tComponent\n"
1471                                        "override\t{0A00FB1D-97B0-4B42-ADF0-BB8913416623}\tMSITESTDIR\t0\t\toverride.txt\n"
1472                                        "preselected\t{44E1DB75-605A-43DD-8CF5-CAB17F1BBD60}\tMSITESTDIR\t0\t\tpreselected.txt\n"
1473                                        "notpreselected\t{E1647733-5E75-400A-A92E-5E60B4D4EF9F}\tMSITESTDIR\t0\t\tnotpreselected.txt\n";
1474
1475 static const CHAR fo_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1476                                            "s72\ti2\tS64\tS0\tS255\n"
1477                                            "CustomAction\tAction\n"
1478                                            "SetPreselected\t51\tPreselected\t1\t\n";
1479
1480 static const CHAR fo_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1481                                               "s72\tS255\tI2\n"
1482                                               "InstallExecuteSequence\tAction\n"
1483                                               "LaunchConditions\t\t100\n"
1484                                               "SetPreselected\tpreselect=1\t200\n"
1485                                               "CostInitialize\t\t800\n"
1486                                               "FileCost\t\t900\n"
1487                                               "CostFinalize\t\t1000\n"
1488                                               "InstallValidate\t\t1400\n"
1489                                               "InstallInitialize\t\t1500\n"
1490                                               "ProcessComponents\t\t1600\n"
1491                                               "RemoveFiles\t\t1700\n"
1492                                               "InstallFiles\t\t2000\n"
1493                                               "RegisterProduct\t\t5000\n"
1494                                               "PublishFeatures\t\t5100\n"
1495                                               "PublishProduct\t\t5200\n"
1496                                               "InstallFinalize\t\t6000\n";
1497
1498 static const CHAR pub_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1499                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1500                                    "File\tFile\n"
1501                                    "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n";
1502
1503 static const CHAR pub_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1504                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1505                                       "Feature\tFeature\n"
1506                                       "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n";
1507
1508 static const CHAR pub_feature_comp_dat[] = "Feature_\tComponent_\n"
1509                                            "s38\ts72\n"
1510                                            "FeatureComponents\tFeature_\tComponent_\n"
1511                                            "publish\tpublish\n";
1512
1513 static const CHAR pub_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1514                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1515                                         "Component\tComponent\n"
1516                                         "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n";
1517
1518 static const CHAR pub_publish_component_dat[] = "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n"
1519                                                 "s38\ts255\ts72\tL255\ts38\n"
1520                                                 "PublishComponent\tComponentId\tQualifier\tComponent_\n"
1521                                                 "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n";
1522
1523 static const CHAR pub_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1524                                                "s72\tS255\tI2\n"
1525                                                "InstallExecuteSequence\tAction\n"
1526                                                "LaunchConditions\t\t100\n"
1527                                                "CostInitialize\t\t800\n"
1528                                                "FileCost\t\t900\n"
1529                                                "CostFinalize\t\t1000\n"
1530                                                "InstallValidate\t\t1400\n"
1531                                                "InstallInitialize\t\t1500\n"
1532                                                "ProcessComponents\t\t1600\n"
1533                                                "RemoveFiles\t\t1700\n"
1534                                                "InstallFiles\t\t2000\n"
1535                                                "PublishComponents\t\t3000\n"
1536                                                "UnpublishComponents\t\t3100\n"
1537                                                "RegisterProduct\t\t5000\n"
1538                                                "PublishFeatures\t\t5100\n"
1539                                                "PublishProduct\t\t5200\n"
1540                                                "InstallFinalize\t\t6000\n";
1541
1542 static const CHAR rd_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1543                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1544                                   "File\tFile\n"
1545                                   "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n"
1546                                   "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n"
1547                                   "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n";
1548
1549 static const CHAR rd_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1550                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1551                                      "Feature\tFeature\n"
1552                                      "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n";
1553
1554 static const CHAR rd_feature_comp_dat[] = "Feature_\tComponent_\n"
1555                                           "s38\ts72\n"
1556                                           "FeatureComponents\tFeature_\tComponent_\n"
1557                                           "duplicate\tduplicate\n";
1558
1559 static const CHAR rd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1560                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
1561                                        "Component\tComponent\n"
1562                                        "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n"
1563                                        "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n";
1564
1565 static const CHAR rd_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
1566                                             "s72\ts72\ts72\tS255\tS72\n"
1567                                             "DuplicateFile\tFileKey\n"
1568                                             "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n"
1569                                             "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n"
1570                                             "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n";
1571
1572 static const CHAR rd_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1573                                               "s72\tS255\tI2\n"
1574                                               "InstallExecuteSequence\tAction\n"
1575                                               "LaunchConditions\t\t100\n"
1576                                               "CostInitialize\t\t800\n"
1577                                               "FileCost\t\t900\n"
1578                                               "CostFinalize\t\t1000\n"
1579                                               "InstallValidate\t\t1400\n"
1580                                               "InstallInitialize\t\t1500\n"
1581                                               "ProcessComponents\t\t1600\n"
1582                                               "RemoveDuplicateFiles\t\t1900\n"
1583                                               "InstallFiles\t\t2000\n"
1584                                               "DuplicateFiles\t\t2100\n"
1585                                               "RegisterProduct\t\t5000\n"
1586                                               "PublishFeatures\t\t5100\n"
1587                                               "PublishProduct\t\t5200\n"
1588                                               "InstallFinalize\t\t6000\n";
1589
1590 static const CHAR rrv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1591                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1592                                    "File\tFile\n"
1593                                    "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n";
1594
1595 static const CHAR rrv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1596                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1597                                       "Feature\tFeature\n"
1598                                       "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n";
1599
1600 static const CHAR rrv_feature_comp_dat[] = "Feature_\tComponent_\n"
1601                                            "s38\ts72\n"
1602                                            "FeatureComponents\tFeature_\tComponent_\n"
1603                                            "registry\tregistry\n";
1604
1605 static const CHAR rrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1606                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1607                                         "Component\tComponent\n"
1608                                         "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n";
1609
1610 static const CHAR rrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
1611                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
1612                                        "Registry\tRegistry\n"
1613                                        "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n"
1614                                        "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n"
1615                                        "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n";
1616
1617 static const CHAR rrv_remove_registry_dat[] = "RemoveRegistry\tRoot\tKey\tName\tComponent_\n"
1618                                               "s72\ti2\tl255\tL255\ts72\n"
1619                                               "RemoveRegistry\tRemoveRegistry\n"
1620                                               "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n"
1621                                               "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n"
1622                                               "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n";
1623
1624 static const CHAR rrv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1625                                                "s72\tS255\tI2\n"
1626                                                "InstallExecuteSequence\tAction\n"
1627                                                "LaunchConditions\t\t100\n"
1628                                                "CostInitialize\t\t800\n"
1629                                                "FileCost\t\t900\n"
1630                                                "CostFinalize\t\t1000\n"
1631                                                "InstallValidate\t\t1400\n"
1632                                                "InstallInitialize\t\t1500\n"
1633                                                "ProcessComponents\t\t1600\n"
1634                                                "RemoveFiles\t\t1700\n"
1635                                                "InstallFiles\t\t2000\n"
1636                                                "RemoveRegistryValues\t\t3000\n"
1637                                                "RegisterProduct\t\t5000\n"
1638                                                "PublishFeatures\t\t5100\n"
1639                                                "PublishProduct\t\t5200\n"
1640                                                "InstallFinalize\t\t6000\n";
1641
1642 static const CHAR frp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1643                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1644                                    "File\tFile\n"
1645                                    "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n";
1646
1647 static const CHAR frp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1648                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1649                                       "Feature\tFeature\n"
1650                                       "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n";
1651
1652 static const CHAR frp_feature_comp_dat[] = "Feature_\tComponent_\n"
1653                                            "s38\ts72\n"
1654                                            "FeatureComponents\tFeature_\tComponent_\n"
1655                                            "product\tproduct\n";
1656
1657 static const CHAR frp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1658                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1659                                         "Component\tComponent\n"
1660                                         "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n";
1661
1662 static const CHAR frp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
1663                                             "s72\ti2\tS64\tS0\tS255\n"
1664                                             "CustomAction\tAction\n"
1665                                             "TestProp\t19\t\t\tPROP set\n";
1666
1667 static const CHAR frp_upgrade_dat[] = "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1668                                       "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1669                                       "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1670                                       "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n";
1671
1672 static const CHAR frp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1673                                                "s72\tS255\tI2\n"
1674                                                "InstallExecuteSequence\tAction\n"
1675                                                "FindRelatedProducts\t\t50\n"
1676                                                "TestProp\tPROP AND NOT REMOVE\t51\n"
1677                                                "LaunchConditions\t\t100\n"
1678                                                "CostInitialize\t\t800\n"
1679                                                "FileCost\t\t900\n"
1680                                                "CostFinalize\t\t1000\n"
1681                                                "InstallValidate\t\t1400\n"
1682                                                "InstallInitialize\t\t1500\n"
1683                                                "ProcessComponents\t\t1600\n"
1684                                                "RemoveFiles\t\t1700\n"
1685                                                "InstallFiles\t\t2000\n"
1686                                                "RegisterProduct\t\t5000\n"
1687                                                "PublishFeatures\t\t5100\n"
1688                                                "PublishProduct\t\t5200\n"
1689                                                "InstallFinalize\t\t6000\n";
1690
1691 static const CHAR riv_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1692                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1693                                    "File\tFile\n"
1694                                    "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n";
1695
1696 static const CHAR riv_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1697                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1698                                       "Feature\tFeature\n"
1699                                       "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n";
1700
1701 static const CHAR riv_feature_comp_dat[] = "Feature_\tComponent_\n"
1702                                            "s38\ts72\n"
1703                                            "FeatureComponents\tFeature_\tComponent_\n"
1704                                            "inifile\tinifile\n";
1705
1706 static const CHAR riv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1707                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1708                                         "Component\tComponent\n"
1709                                         "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n";
1710
1711 static const CHAR riv_ini_file_dat[] = "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1712                                        "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n"
1713                                        "IniFile\tIniFile\n"
1714                                        "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n";
1715
1716 static const CHAR riv_remove_ini_file_dat[] = "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1717                                               "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n"
1718                                               "RemoveIniFile\tRemoveIniFile\n"
1719                                               "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n";
1720
1721 static const CHAR riv_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1722                                                "s72\tS255\tI2\n"
1723                                                "InstallExecuteSequence\tAction\n"
1724                                                "LaunchConditions\t\t100\n"
1725                                                "CostInitialize\t\t800\n"
1726                                                "FileCost\t\t900\n"
1727                                                "CostFinalize\t\t1000\n"
1728                                                "InstallValidate\t\t1400\n"
1729                                                "InstallInitialize\t\t1500\n"
1730                                                "ProcessComponents\t\t1600\n"
1731                                                "RemoveFiles\t\t1700\n"
1732                                                "InstallFiles\t\t2000\n"
1733                                                "RemoveIniValues\t\t3000\n"
1734                                                "RegisterProduct\t\t5000\n"
1735                                                "PublishFeatures\t\t5100\n"
1736                                                "PublishProduct\t\t5200\n"
1737                                                "InstallFinalize\t\t6000\n";
1738
1739 static const CHAR res_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1740                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1741                                    "File\tFile\n"
1742                                    "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n";
1743
1744 static const CHAR res_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1745                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1746                                       "Feature\tFeature\n"
1747                                       "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n";
1748
1749 static const CHAR res_feature_comp_dat[] = "Feature_\tComponent_\n"
1750                                            "s38\ts72\n"
1751                                            "FeatureComponents\tFeature_\tComponent_\n"
1752                                            "envvar\tenvvar\n";
1753
1754 static const CHAR res_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1755                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1756                                         "Component\tComponent\n"
1757                                         "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n";
1758
1759 static const CHAR res_environment_dat[] = "Environment\tName\tValue\tComponent_\n"
1760                                           "s72\tl255\tL255\ts72\n"
1761                                           "Environment\tEnvironment\n"
1762                                           "var1\t=-MSITESTVAR1\t1\tenvvar\n"
1763                                           "var2\t=+-MSITESTVAR2\t1\tenvvar\n"
1764                                           "var3\t=MSITESTVAR3\t1\tenvvar\n"
1765                                           "var4\t=-MSITESTVAR4\t\tenvvar\n"
1766                                           "var5\t=MSITESTVAR5\t\tenvvar\n";
1767
1768 static const CHAR res_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1769                                                "s72\tS255\tI2\n"
1770                                                "InstallExecuteSequence\tAction\n"
1771                                                "LaunchConditions\t\t100\n"
1772                                                "CostInitialize\t\t800\n"
1773                                                "FileCost\t\t900\n"
1774                                                "CostFinalize\t\t1000\n"
1775                                                "InstallValidate\t\t1400\n"
1776                                                "InstallInitialize\t\t1500\n"
1777                                                "ProcessComponents\t\t1600\n"
1778                                                "RemoveFiles\t\t1700\n"
1779                                                "InstallFiles\t\t2000\n"
1780                                                "RemoveEnvironmentStrings\t\t3000\n"
1781                                                "RegisterProduct\t\t5000\n"
1782                                                "PublishFeatures\t\t5100\n"
1783                                                "PublishProduct\t\t5200\n"
1784                                                "InstallFinalize\t\t6000\n";
1785
1786 static const CHAR rci_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1787                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1788                                    "File\tFile\n"
1789                                    "class.txt\tclass\tclass.txt\t1000\t\t\t8192\t1\n";
1790
1791 static const CHAR rci_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1792                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1793                                       "Feature\tFeature\n"
1794                                       "class\t\t\tclass feature\t1\t2\tMSITESTDIR\t0\n";
1795
1796 static const CHAR rci_feature_comp_dat[] = "Feature_\tComponent_\n"
1797                                            "s38\ts72\n"
1798                                            "FeatureComponents\tFeature_\tComponent_\n"
1799                                            "class\tclass\n";
1800
1801 static const CHAR rci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1802                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1803                                         "Component\tComponent\n"
1804                                         "class\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tclass.txt\n";
1805
1806 static const CHAR rci_appid_dat[] = "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n"
1807                                     "s38\tS255\tS255\tS255\tS255\tI2\tI2\n"
1808                                     "AppId\tAppId\n"
1809                                     "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n";
1810
1811 static const CHAR rci_class_dat[] = "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n"
1812                                     "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n"
1813                                     "Class\tCLSID\tContext\tComponent_\n"
1814                                     "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tclass\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tclass\t\n";
1815
1816 static const CHAR rci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1817                                                "s72\tS255\tI2\n"
1818                                                "InstallExecuteSequence\tAction\n"
1819                                                "LaunchConditions\t\t100\n"
1820                                                "CostInitialize\t\t800\n"
1821                                                "FileCost\t\t900\n"
1822                                                "CostFinalize\t\t1000\n"
1823                                                "InstallValidate\t\t1400\n"
1824                                                "InstallInitialize\t\t1500\n"
1825                                                "ProcessComponents\t\t1600\n"
1826                                                "RemoveFiles\t\t1700\n"
1827                                                "InstallFiles\t\t2000\n"
1828                                                "UnregisterClassInfo\t\t3000\n"
1829                                                "RegisterClassInfo\t\t4000\n"
1830                                                "RegisterProduct\t\t5000\n"
1831                                                "PublishFeatures\t\t5100\n"
1832                                                "PublishProduct\t\t5200\n"
1833                                                "InstallFinalize\t\t6000\n";
1834
1835 static const CHAR rei_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1836                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1837                                    "File\tFile\n"
1838                                    "extension.txt\textension\textension.txt\t1000\t\t\t8192\t1\n";
1839
1840 static const CHAR rei_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1841                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1842                                       "Feature\tFeature\n"
1843                                       "extension\t\t\textension feature\t1\t2\tMSITESTDIR\t0\n";
1844
1845 static const CHAR rei_feature_comp_dat[] = "Feature_\tComponent_\n"
1846                                            "s38\ts72\n"
1847                                            "FeatureComponents\tFeature_\tComponent_\n"
1848                                            "extension\textension\n";
1849
1850 static const CHAR rei_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1851                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1852                                         "Component\tComponent\n"
1853                                         "extension\t{9A3060D4-60BA-4A82-AB55-9FB148AD013C}\tMSITESTDIR\t0\t\textension.txt\n";
1854
1855 static const CHAR rei_extension_dat[] = "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1856                                         "s255\ts72\tS255\tS64\ts38\n"
1857                                         "Extension\tExtension\tComponent_\n"
1858                                         "extension\textension\tProg.Id.1\t\textension\n";
1859
1860 static const CHAR rei_verb_dat[] = "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1861                                    "s255\ts32\tI2\tL255\tL255\n"
1862                                    "Verb\tExtension_\tVerb\n"
1863                                    "extension\tOpen\t1\t&Open\t/argument\n";
1864
1865 static const CHAR rei_progid_dat[] = "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n"
1866                                      "s255\tS255\tS38\tL255\tS72\tI2\n"
1867                                      "ProgId\tProgId\n"
1868                                      "Prog.Id.1\t\t\tdescription\t\t\n";
1869
1870 static const CHAR rei_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1871                                                "s72\tS255\tI2\n"
1872                                                "InstallExecuteSequence\tAction\n"
1873                                                "LaunchConditions\t\t100\n"
1874                                                "CostInitialize\t\t800\n"
1875                                                "FileCost\t\t900\n"
1876                                                "CostFinalize\t\t1000\n"
1877                                                "InstallValidate\t\t1400\n"
1878                                                "InstallInitialize\t\t1500\n"
1879                                                "ProcessComponents\t\t1600\n"
1880                                                "RemoveFiles\t\t1700\n"
1881                                                "InstallFiles\t\t2000\n"
1882                                                "UnregisterExtensionInfo\t\t3000\n"
1883                                                "RegisterExtensionInfo\t\t4000\n"
1884                                                "RegisterProduct\t\t5000\n"
1885                                                "PublishFeatures\t\t5100\n"
1886                                                "PublishProduct\t\t5200\n"
1887                                                "InstallFinalize\t\t6000\n";
1888
1889 static const CHAR rmi_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1890                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1891                                    "File\tFile\n"
1892                                    "mime.txt\tmime\tmime.txt\t1000\t\t\t8192\t1\n";
1893
1894 static const CHAR rmi_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1895                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1896                                       "Feature\tFeature\n"
1897                                       "mime\t\t\tmime feature\t1\t2\tMSITESTDIR\t0\n";
1898
1899 static const CHAR rmi_feature_comp_dat[] = "Feature_\tComponent_\n"
1900                                            "s38\ts72\n"
1901                                            "FeatureComponents\tFeature_\tComponent_\n"
1902                                            "mime\tmime\n";
1903
1904 static const CHAR rmi_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1905                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
1906                                         "Component\tComponent\n"
1907                                         "mime\t{A1D630CE-13A7-4882-AFDD-148E2BBAFC6D}\tMSITESTDIR\t0\t\tmime.txt\n";
1908
1909 static const CHAR rmi_extension_dat[] = "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1910                                         "s255\ts72\tS255\tS64\ts38\n"
1911                                         "Extension\tExtension\tComponent_\n"
1912                                         "mime\tmime\t\tmime/type\tmime\n";
1913
1914 static const CHAR rmi_verb_dat[] = "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1915                                    "s255\ts32\tI2\tL255\tL255\n"
1916                                    "Verb\tExtension_\tVerb\n"
1917                                    "mime\tOpen\t1\t&Open\t/argument\n";
1918
1919 static const CHAR rmi_mime_dat[] = "ContentType\tExtension_\tCLSID\n"
1920                                    "s64\ts255\tS38\n"
1921                                    "MIME\tContentType\n"
1922                                    "mime/type\tmime\t\n";
1923
1924 static const CHAR rmi_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
1925                                                "s72\tS255\tI2\n"
1926                                                "InstallExecuteSequence\tAction\n"
1927                                                "LaunchConditions\t\t100\n"
1928                                                "CostInitialize\t\t800\n"
1929                                                "FileCost\t\t900\n"
1930                                                "CostFinalize\t\t1000\n"
1931                                                "InstallValidate\t\t1400\n"
1932                                                "InstallInitialize\t\t1500\n"
1933                                                "ProcessComponents\t\t1600\n"
1934                                                "RemoveFiles\t\t1700\n"
1935                                                "InstallFiles\t\t2000\n"
1936                                                "UnregisterExtensionInfo\t\t3000\n"
1937                                                "UnregisterMIMEInfo\t\t3500\n"
1938                                                "RegisterExtensionInfo\t\t4000\n"
1939                                                "RegisterMIMEInfo\t\t4500\n"
1940                                                "RegisterProduct\t\t5000\n"
1941                                                "PublishFeatures\t\t5100\n"
1942                                                "PublishProduct\t\t5200\n"
1943                                                "InstallFinalize\t\t6000\n";
1944
1945 typedef struct _msi_table
1946 {
1947     const CHAR *filename;
1948     const CHAR *data;
1949     int size;
1950 } msi_table;
1951
1952 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
1953
1954 static const msi_table tables[] =
1955 {
1956     ADD_TABLE(component),
1957     ADD_TABLE(directory),
1958     ADD_TABLE(feature),
1959     ADD_TABLE(feature_comp),
1960     ADD_TABLE(file),
1961     ADD_TABLE(install_exec_seq),
1962     ADD_TABLE(media),
1963     ADD_TABLE(property),
1964     ADD_TABLE(registry),
1965     ADD_TABLE(service_install),
1966     ADD_TABLE(service_control)
1967 };
1968
1969 static const msi_table sc_tables[] =
1970 {
1971     ADD_TABLE(component),
1972     ADD_TABLE(directory),
1973     ADD_TABLE(feature),
1974     ADD_TABLE(feature_comp),
1975     ADD_TABLE(file),
1976     ADD_TABLE(install_exec_seq),
1977     ADD_TABLE(media),
1978     ADD_TABLE(property),
1979     ADD_TABLE(shortcut)
1980 };
1981
1982 static const msi_table ps_tables[] =
1983 {
1984     ADD_TABLE(component),
1985     ADD_TABLE(directory),
1986     ADD_TABLE(feature),
1987     ADD_TABLE(feature_comp),
1988     ADD_TABLE(file),
1989     ADD_TABLE(install_exec_seq),
1990     ADD_TABLE(media),
1991     ADD_TABLE(property),
1992     ADD_TABLE(condition)
1993 };
1994
1995 static const msi_table env_tables[] =
1996 {
1997     ADD_TABLE(component),
1998     ADD_TABLE(directory),
1999     ADD_TABLE(feature),
2000     ADD_TABLE(feature_comp),
2001     ADD_TABLE(file),
2002     ADD_TABLE(install_exec_seq),
2003     ADD_TABLE(media),
2004     ADD_TABLE(property),
2005     ADD_TABLE(environment)
2006 };
2007
2008 static const msi_table up_tables[] =
2009 {
2010     ADD_TABLE(component),
2011     ADD_TABLE(directory),
2012     ADD_TABLE(feature),
2013     ADD_TABLE(feature_comp),
2014     ADD_TABLE(file),
2015     ADD_TABLE(install_exec_seq),
2016     ADD_TABLE(media),
2017     ADD_TABLE(up_property),
2018     ADD_TABLE(registry),
2019     ADD_TABLE(service_install),
2020     ADD_TABLE(service_control)
2021 };
2022
2023 static const msi_table up2_tables[] =
2024 {
2025     ADD_TABLE(component),
2026     ADD_TABLE(directory),
2027     ADD_TABLE(feature),
2028     ADD_TABLE(feature_comp),
2029     ADD_TABLE(file),
2030     ADD_TABLE(install_exec_seq),
2031     ADD_TABLE(media),
2032     ADD_TABLE(up2_property),
2033     ADD_TABLE(registry),
2034     ADD_TABLE(service_install),
2035     ADD_TABLE(service_control)
2036 };
2037
2038 static const msi_table up3_tables[] =
2039 {
2040     ADD_TABLE(component),
2041     ADD_TABLE(directory),
2042     ADD_TABLE(feature),
2043     ADD_TABLE(feature_comp),
2044     ADD_TABLE(file),
2045     ADD_TABLE(install_exec_seq),
2046     ADD_TABLE(media),
2047     ADD_TABLE(up3_property),
2048     ADD_TABLE(registry),
2049     ADD_TABLE(service_install),
2050     ADD_TABLE(service_control)
2051 };
2052
2053 static const msi_table up4_tables[] =
2054 {
2055     ADD_TABLE(component),
2056     ADD_TABLE(directory),
2057     ADD_TABLE(feature),
2058     ADD_TABLE(feature_comp),
2059     ADD_TABLE(file),
2060     ADD_TABLE(pp_install_exec_seq),
2061     ADD_TABLE(media),
2062     ADD_TABLE(property),
2063     ADD_TABLE(registry),
2064     ADD_TABLE(service_install),
2065     ADD_TABLE(service_control)
2066 };
2067
2068 static const msi_table up5_tables[] =
2069 {
2070     ADD_TABLE(component),
2071     ADD_TABLE(directory),
2072     ADD_TABLE(feature),
2073     ADD_TABLE(feature_comp),
2074     ADD_TABLE(file),
2075     ADD_TABLE(pp_install_exec_seq),
2076     ADD_TABLE(media),
2077     ADD_TABLE(up_property),
2078     ADD_TABLE(registry),
2079     ADD_TABLE(service_install),
2080     ADD_TABLE(service_control)
2081 };
2082
2083 static const msi_table up6_tables[] =
2084 {
2085     ADD_TABLE(component),
2086     ADD_TABLE(directory),
2087     ADD_TABLE(feature),
2088     ADD_TABLE(feature_comp),
2089     ADD_TABLE(file),
2090     ADD_TABLE(pp_install_exec_seq),
2091     ADD_TABLE(media),
2092     ADD_TABLE(up2_property),
2093     ADD_TABLE(registry),
2094     ADD_TABLE(service_install),
2095     ADD_TABLE(service_control)
2096 };
2097
2098 static const msi_table up7_tables[] =
2099 {
2100     ADD_TABLE(component),
2101     ADD_TABLE(directory),
2102     ADD_TABLE(feature),
2103     ADD_TABLE(feature_comp),
2104     ADD_TABLE(file),
2105     ADD_TABLE(pp_install_exec_seq),
2106     ADD_TABLE(media),
2107     ADD_TABLE(up3_property),
2108     ADD_TABLE(registry),
2109     ADD_TABLE(service_install),
2110     ADD_TABLE(service_control)
2111 };
2112
2113 static const msi_table cc_tables[] =
2114 {
2115     ADD_TABLE(cc_component),
2116     ADD_TABLE(directory),
2117     ADD_TABLE(cc_feature),
2118     ADD_TABLE(cc_feature_comp),
2119     ADD_TABLE(cc_file),
2120     ADD_TABLE(install_exec_seq),
2121     ADD_TABLE(cc_media),
2122     ADD_TABLE(property),
2123 };
2124
2125 static const msi_table cc2_tables[] =
2126 {
2127     ADD_TABLE(cc2_component),
2128     ADD_TABLE(directory),
2129     ADD_TABLE(cc_feature),
2130     ADD_TABLE(cc_feature_comp),
2131     ADD_TABLE(cc2_file),
2132     ADD_TABLE(install_exec_seq),
2133     ADD_TABLE(cc_media),
2134     ADD_TABLE(property),
2135 };
2136
2137 static const msi_table co_tables[] =
2138 {
2139     ADD_TABLE(cc_component),
2140     ADD_TABLE(directory),
2141     ADD_TABLE(cc_feature),
2142     ADD_TABLE(cc_feature_comp),
2143     ADD_TABLE(co_file),
2144     ADD_TABLE(install_exec_seq),
2145     ADD_TABLE(co_media),
2146     ADD_TABLE(property),
2147 };
2148
2149 static const msi_table co2_tables[] =
2150 {
2151     ADD_TABLE(cc_component),
2152     ADD_TABLE(directory),
2153     ADD_TABLE(cc_feature),
2154     ADD_TABLE(cc_feature_comp),
2155     ADD_TABLE(cc_file),
2156     ADD_TABLE(install_exec_seq),
2157     ADD_TABLE(co2_media),
2158     ADD_TABLE(property),
2159 };
2160
2161 static const msi_table mm_tables[] =
2162 {
2163     ADD_TABLE(cc_component),
2164     ADD_TABLE(directory),
2165     ADD_TABLE(cc_feature),
2166     ADD_TABLE(cc_feature_comp),
2167     ADD_TABLE(mm_file),
2168     ADD_TABLE(install_exec_seq),
2169     ADD_TABLE(mm_media),
2170     ADD_TABLE(property),
2171 };
2172
2173 static const msi_table ss_tables[] =
2174 {
2175     ADD_TABLE(cc_component),
2176     ADD_TABLE(directory),
2177     ADD_TABLE(cc_feature),
2178     ADD_TABLE(cc_feature_comp),
2179     ADD_TABLE(cc_file),
2180     ADD_TABLE(install_exec_seq),
2181     ADD_TABLE(ss_media),
2182     ADD_TABLE(property),
2183 };
2184
2185 static const msi_table ui_tables[] =
2186 {
2187     ADD_TABLE(ui_component),
2188     ADD_TABLE(directory),
2189     ADD_TABLE(cc_feature),
2190     ADD_TABLE(cc_feature_comp),
2191     ADD_TABLE(cc_file),
2192     ADD_TABLE(install_exec_seq),
2193     ADD_TABLE(ui_install_ui_seq),
2194     ADD_TABLE(ui_custom_action),
2195     ADD_TABLE(cc_media),
2196     ADD_TABLE(property),
2197 };
2198
2199 static const msi_table rof_tables[] =
2200 {
2201     ADD_TABLE(rof_component),
2202     ADD_TABLE(directory),
2203     ADD_TABLE(rof_feature),
2204     ADD_TABLE(rof_feature_comp),
2205     ADD_TABLE(rof_file),
2206     ADD_TABLE(install_exec_seq),
2207     ADD_TABLE(rof_media),
2208     ADD_TABLE(property),
2209 };
2210
2211 static const msi_table rofc_tables[] =
2212 {
2213     ADD_TABLE(rof_component),
2214     ADD_TABLE(directory),
2215     ADD_TABLE(rof_feature),
2216     ADD_TABLE(rof_feature_comp),
2217     ADD_TABLE(rofc_file),
2218     ADD_TABLE(install_exec_seq),
2219     ADD_TABLE(rofc_media),
2220     ADD_TABLE(property),
2221 };
2222
2223 static const msi_table sdp_tables[] =
2224 {
2225     ADD_TABLE(rof_component),
2226     ADD_TABLE(directory),
2227     ADD_TABLE(rof_feature),
2228     ADD_TABLE(rof_feature_comp),
2229     ADD_TABLE(rof_file),
2230     ADD_TABLE(sdp_install_exec_seq),
2231     ADD_TABLE(sdp_custom_action),
2232     ADD_TABLE(rof_media),
2233     ADD_TABLE(property),
2234 };
2235
2236 static const msi_table cie_tables[] =
2237 {
2238     ADD_TABLE(cie_component),
2239     ADD_TABLE(directory),
2240     ADD_TABLE(cc_feature),
2241     ADD_TABLE(cie_feature_comp),
2242     ADD_TABLE(cie_file),
2243     ADD_TABLE(install_exec_seq),
2244     ADD_TABLE(cie_media),
2245     ADD_TABLE(property),
2246 };
2247
2248 static const msi_table ci_tables[] =
2249 {
2250     ADD_TABLE(ci_component),
2251     ADD_TABLE(directory),
2252     ADD_TABLE(rof_feature),
2253     ADD_TABLE(rof_feature_comp),
2254     ADD_TABLE(rof_file),
2255     ADD_TABLE(ci_install_exec_seq),
2256     ADD_TABLE(rof_media),
2257     ADD_TABLE(property),
2258     ADD_TABLE(ci_custom_action),
2259 };
2260
2261 static const msi_table ci2_tables[] =
2262 {
2263     ADD_TABLE(ci2_component),
2264     ADD_TABLE(directory),
2265     ADD_TABLE(rof_feature),
2266     ADD_TABLE(ci2_feature_comp),
2267     ADD_TABLE(ci2_file),
2268     ADD_TABLE(install_exec_seq),
2269     ADD_TABLE(rof_media),
2270     ADD_TABLE(property),
2271 };
2272
2273 static const msi_table spf_tables[] =
2274 {
2275     ADD_TABLE(ci_component),
2276     ADD_TABLE(directory),
2277     ADD_TABLE(rof_feature),
2278     ADD_TABLE(rof_feature_comp),
2279     ADD_TABLE(rof_file),
2280     ADD_TABLE(spf_install_exec_seq),
2281     ADD_TABLE(rof_media),
2282     ADD_TABLE(property),
2283     ADD_TABLE(spf_custom_action),
2284     ADD_TABLE(spf_install_ui_seq),
2285 };
2286
2287 static const msi_table pp_tables[] =
2288 {
2289     ADD_TABLE(ci_component),
2290     ADD_TABLE(directory),
2291     ADD_TABLE(rof_feature),
2292     ADD_TABLE(rof_feature_comp),
2293     ADD_TABLE(rof_file),
2294     ADD_TABLE(pp_install_exec_seq),
2295     ADD_TABLE(rof_media),
2296     ADD_TABLE(property),
2297 };
2298
2299 static const msi_table ppc_tables[] =
2300 {
2301     ADD_TABLE(ppc_component),
2302     ADD_TABLE(directory),
2303     ADD_TABLE(rof_feature),
2304     ADD_TABLE(ppc_feature_comp),
2305     ADD_TABLE(ppc_file),
2306     ADD_TABLE(pp_install_exec_seq),
2307     ADD_TABLE(ppc_media),
2308     ADD_TABLE(property),
2309 };
2310
2311 static const msi_table lus0_tables[] =
2312 {
2313     ADD_TABLE(ci_component),
2314     ADD_TABLE(directory),
2315     ADD_TABLE(rof_feature),
2316     ADD_TABLE(rof_feature_comp),
2317     ADD_TABLE(rof_file),
2318     ADD_TABLE(pp_install_exec_seq),
2319     ADD_TABLE(rof_media),
2320     ADD_TABLE(property),
2321 };
2322
2323 static const msi_table lus1_tables[] =
2324 {
2325     ADD_TABLE(ci_component),
2326     ADD_TABLE(directory),
2327     ADD_TABLE(rof_feature),
2328     ADD_TABLE(rof_feature_comp),
2329     ADD_TABLE(rof_file),
2330     ADD_TABLE(pp_install_exec_seq),
2331     ADD_TABLE(rofc_media),
2332     ADD_TABLE(property),
2333 };
2334
2335 static const msi_table lus2_tables[] =
2336 {
2337     ADD_TABLE(ci_component),
2338     ADD_TABLE(directory),
2339     ADD_TABLE(rof_feature),
2340     ADD_TABLE(rof_feature_comp),
2341     ADD_TABLE(rof_file),
2342     ADD_TABLE(pp_install_exec_seq),
2343     ADD_TABLE(lus2_media),
2344     ADD_TABLE(property),
2345 };
2346
2347 static const msi_table tp_tables[] =
2348 {
2349     ADD_TABLE(tp_component),
2350     ADD_TABLE(directory),
2351     ADD_TABLE(rof_feature),
2352     ADD_TABLE(ci2_feature_comp),
2353     ADD_TABLE(ci2_file),
2354     ADD_TABLE(install_exec_seq),
2355     ADD_TABLE(rof_media),
2356     ADD_TABLE(property),
2357 };
2358
2359 static const msi_table cwd_tables[] =
2360 {
2361     ADD_TABLE(cwd_component),
2362     ADD_TABLE(directory),
2363     ADD_TABLE(rof_feature),
2364     ADD_TABLE(ci2_feature_comp),
2365     ADD_TABLE(ci2_file),
2366     ADD_TABLE(install_exec_seq),
2367     ADD_TABLE(rof_media),
2368     ADD_TABLE(property),
2369 };
2370
2371 static const msi_table adm_tables[] =
2372 {
2373     ADD_TABLE(adm_component),
2374     ADD_TABLE(directory),
2375     ADD_TABLE(rof_feature),
2376     ADD_TABLE(ci2_feature_comp),
2377     ADD_TABLE(ci2_file),
2378     ADD_TABLE(install_exec_seq),
2379     ADD_TABLE(rof_media),
2380     ADD_TABLE(property),
2381     ADD_TABLE(adm_custom_action),
2382     ADD_TABLE(adm_admin_exec_seq),
2383 };
2384
2385 static const msi_table amp_tables[] =
2386 {
2387     ADD_TABLE(amp_component),
2388     ADD_TABLE(directory),
2389     ADD_TABLE(rof_feature),
2390     ADD_TABLE(ci2_feature_comp),
2391     ADD_TABLE(ci2_file),
2392     ADD_TABLE(install_exec_seq),
2393     ADD_TABLE(rof_media),
2394     ADD_TABLE(property),
2395 };
2396
2397 static const msi_table rem_tables[] =
2398 {
2399     ADD_TABLE(rem_component),
2400     ADD_TABLE(directory),
2401     ADD_TABLE(rof_feature),
2402     ADD_TABLE(rem_feature_comp),
2403     ADD_TABLE(rem_file),
2404     ADD_TABLE(rem_install_exec_seq),
2405     ADD_TABLE(rof_media),
2406     ADD_TABLE(property),
2407     ADD_TABLE(rem_remove_files),
2408 };
2409
2410 static const msi_table mov_tables[] =
2411 {
2412     ADD_TABLE(cwd_component),
2413     ADD_TABLE(directory),
2414     ADD_TABLE(rof_feature),
2415     ADD_TABLE(ci2_feature_comp),
2416     ADD_TABLE(ci2_file),
2417     ADD_TABLE(install_exec_seq),
2418     ADD_TABLE(rof_media),
2419     ADD_TABLE(property),
2420     ADD_TABLE(mov_move_file),
2421 };
2422
2423 static const msi_table mc_tables[] =
2424 {
2425     ADD_TABLE(mc_component),
2426     ADD_TABLE(directory),
2427     ADD_TABLE(cc_feature),
2428     ADD_TABLE(cie_feature_comp),
2429     ADD_TABLE(mc_file),
2430     ADD_TABLE(install_exec_seq),
2431     ADD_TABLE(mc_media),
2432     ADD_TABLE(property),
2433     ADD_TABLE(mc_file_hash),
2434 };
2435
2436 static const msi_table df_tables[] =
2437 {
2438     ADD_TABLE(rof_component),
2439     ADD_TABLE(df_directory),
2440     ADD_TABLE(rof_feature),
2441     ADD_TABLE(rof_feature_comp),
2442     ADD_TABLE(rof_file),
2443     ADD_TABLE(install_exec_seq),
2444     ADD_TABLE(rof_media),
2445     ADD_TABLE(property),
2446     ADD_TABLE(df_duplicate_file),
2447 };
2448
2449 static const msi_table wrv_tables[] =
2450 {
2451     ADD_TABLE(wrv_component),
2452     ADD_TABLE(directory),
2453     ADD_TABLE(rof_feature),
2454     ADD_TABLE(ci2_feature_comp),
2455     ADD_TABLE(ci2_file),
2456     ADD_TABLE(install_exec_seq),
2457     ADD_TABLE(rof_media),
2458     ADD_TABLE(property),
2459     ADD_TABLE(wrv_registry),
2460 };
2461
2462 static const msi_table sf_tables[] =
2463 {
2464     ADD_TABLE(wrv_component),
2465     ADD_TABLE(directory),
2466     ADD_TABLE(rof_feature),
2467     ADD_TABLE(ci2_feature_comp),
2468     ADD_TABLE(ci2_file),
2469     ADD_TABLE(install_exec_seq),
2470     ADD_TABLE(rof_media),
2471     ADD_TABLE(property),
2472 };
2473
2474 static const msi_table ca51_tables[] =
2475 {
2476     ADD_TABLE(ca51_component),
2477     ADD_TABLE(directory),
2478     ADD_TABLE(rof_feature),
2479     ADD_TABLE(ci2_feature_comp),
2480     ADD_TABLE(ci2_file),
2481     ADD_TABLE(ca51_install_exec_seq),
2482     ADD_TABLE(rof_media),
2483     ADD_TABLE(property),
2484     ADD_TABLE(ca51_custom_action),
2485 };
2486
2487 static const msi_table is_tables[] =
2488 {
2489     ADD_TABLE(is_component),
2490     ADD_TABLE(directory),
2491     ADD_TABLE(is_feature),
2492     ADD_TABLE(is_feature_comp),
2493     ADD_TABLE(is_file),
2494     ADD_TABLE(install_exec_seq),
2495     ADD_TABLE(is_media),
2496     ADD_TABLE(property),
2497 };
2498
2499 static const msi_table sp_tables[] =
2500 {
2501     ADD_TABLE(sp_component),
2502     ADD_TABLE(sp_directory),
2503     ADD_TABLE(rof_feature),
2504     ADD_TABLE(ci2_feature_comp),
2505     ADD_TABLE(ci2_file),
2506     ADD_TABLE(install_exec_seq),
2507     ADD_TABLE(rof_media),
2508     ADD_TABLE(property),
2509 };
2510
2511 static const msi_table mcp_tables[] =
2512 {
2513     ADD_TABLE(mcp_component),
2514     ADD_TABLE(directory),
2515     ADD_TABLE(mcp_feature),
2516     ADD_TABLE(mcp_feature_comp),
2517     ADD_TABLE(rem_file),
2518     ADD_TABLE(rem_install_exec_seq),
2519     ADD_TABLE(rof_media),
2520     ADD_TABLE(property),
2521 };
2522
2523 static const msi_table mcomp_tables[] =
2524 {
2525     ADD_TABLE(mcp_component),
2526     ADD_TABLE(directory),
2527     ADD_TABLE(mcp_feature),
2528     ADD_TABLE(mcp_feature_comp),
2529     ADD_TABLE(mcomp_file),
2530     ADD_TABLE(rem_install_exec_seq),
2531     ADD_TABLE(rof_media),
2532     ADD_TABLE(property),
2533 };
2534
2535 static const msi_table ai_tables[] =
2536 {
2537     ADD_TABLE(component),
2538     ADD_TABLE(directory),
2539     ADD_TABLE(feature),
2540     ADD_TABLE(feature_comp),
2541     ADD_TABLE(ai_file),
2542     ADD_TABLE(install_exec_seq),
2543     ADD_TABLE(media),
2544     ADD_TABLE(property)
2545 };
2546
2547 static const msi_table pc_tables[] =
2548 {
2549     ADD_TABLE(ca51_component),
2550     ADD_TABLE(directory),
2551     ADD_TABLE(rof_feature),
2552     ADD_TABLE(ci2_feature_comp),
2553     ADD_TABLE(ci2_file),
2554     ADD_TABLE(install_exec_seq),
2555     ADD_TABLE(rof_media),
2556     ADD_TABLE(property)
2557 };
2558
2559 static const msi_table ip_tables[] =
2560 {
2561     ADD_TABLE(component),
2562     ADD_TABLE(directory),
2563     ADD_TABLE(feature),
2564     ADD_TABLE(feature_comp),
2565     ADD_TABLE(file),
2566     ADD_TABLE(ip_install_exec_seq),
2567     ADD_TABLE(ip_custom_action),
2568     ADD_TABLE(media),
2569     ADD_TABLE(property)
2570 };
2571
2572 static const msi_table aup_tables[] =
2573 {
2574     ADD_TABLE(component),
2575     ADD_TABLE(directory),
2576     ADD_TABLE(feature),
2577     ADD_TABLE(feature_comp),
2578     ADD_TABLE(file),
2579     ADD_TABLE(aup_install_exec_seq),
2580     ADD_TABLE(aup_custom_action),
2581     ADD_TABLE(media),
2582     ADD_TABLE(property)
2583 };
2584
2585 static const msi_table aup2_tables[] =
2586 {
2587     ADD_TABLE(component),
2588     ADD_TABLE(directory),
2589     ADD_TABLE(feature),
2590     ADD_TABLE(feature_comp),
2591     ADD_TABLE(file),
2592     ADD_TABLE(aup2_install_exec_seq),
2593     ADD_TABLE(aup_custom_action),
2594     ADD_TABLE(media),
2595     ADD_TABLE(aup_property)
2596 };
2597
2598 static const msi_table aup3_tables[] =
2599 {
2600     ADD_TABLE(component),
2601     ADD_TABLE(directory),
2602     ADD_TABLE(feature),
2603     ADD_TABLE(feature_comp),
2604     ADD_TABLE(file),
2605     ADD_TABLE(aup2_install_exec_seq),
2606     ADD_TABLE(aup_custom_action),
2607     ADD_TABLE(media),
2608     ADD_TABLE(aup2_property)
2609 };
2610
2611 static const msi_table aup4_tables[] =
2612 {
2613     ADD_TABLE(component),
2614     ADD_TABLE(directory),
2615     ADD_TABLE(feature),
2616     ADD_TABLE(feature_comp),
2617     ADD_TABLE(file),
2618     ADD_TABLE(aup3_install_exec_seq),
2619     ADD_TABLE(aup_custom_action),
2620     ADD_TABLE(media),
2621     ADD_TABLE(aup2_property)
2622 };
2623
2624 static const msi_table fiu_tables[] =
2625 {
2626     ADD_TABLE(rof_component),
2627     ADD_TABLE(directory),
2628     ADD_TABLE(rof_feature),
2629     ADD_TABLE(rof_feature_comp),
2630     ADD_TABLE(rof_file),
2631     ADD_TABLE(pp_install_exec_seq),
2632     ADD_TABLE(rof_media),
2633     ADD_TABLE(property),
2634 };
2635
2636 static const msi_table fiuc_tables[] =
2637 {
2638     ADD_TABLE(rof_component),
2639     ADD_TABLE(directory),
2640     ADD_TABLE(rof_feature),
2641     ADD_TABLE(rof_feature_comp),
2642     ADD_TABLE(rofc_file),
2643     ADD_TABLE(pp_install_exec_seq),
2644     ADD_TABLE(rofc_media),
2645     ADD_TABLE(property),
2646 };
2647
2648 static const msi_table cf_tables[] =
2649 {
2650     ADD_TABLE(component),
2651     ADD_TABLE(directory),
2652     ADD_TABLE(feature),
2653     ADD_TABLE(feature_comp),
2654     ADD_TABLE(file),
2655     ADD_TABLE(cf_create_folders),
2656     ADD_TABLE(cf_install_exec_seq),
2657     ADD_TABLE(cf_custom_action),
2658     ADD_TABLE(media),
2659     ADD_TABLE(property)
2660 };
2661
2662 static const msi_table rf_tables[] =
2663 {
2664     ADD_TABLE(component),
2665     ADD_TABLE(directory),
2666     ADD_TABLE(feature),
2667     ADD_TABLE(feature_comp),
2668     ADD_TABLE(file),
2669     ADD_TABLE(cf_create_folders),
2670     ADD_TABLE(rf_install_exec_seq),
2671     ADD_TABLE(cf_custom_action),
2672     ADD_TABLE(media),
2673     ADD_TABLE(property)
2674 };
2675
2676 static const msi_table sss_tables[] =
2677 {
2678     ADD_TABLE(component),
2679     ADD_TABLE(directory),
2680     ADD_TABLE(feature),
2681     ADD_TABLE(feature_comp),
2682     ADD_TABLE(file),
2683     ADD_TABLE(sss_install_exec_seq),
2684     ADD_TABLE(sss_service_control),
2685     ADD_TABLE(media),
2686     ADD_TABLE(property)
2687 };
2688
2689 static const msi_table sds_tables[] =
2690 {
2691     ADD_TABLE(component),
2692     ADD_TABLE(directory),
2693     ADD_TABLE(feature),
2694     ADD_TABLE(feature_comp),
2695     ADD_TABLE(file),
2696     ADD_TABLE(sss_install_exec_seq),
2697     ADD_TABLE(service_control),
2698     ADD_TABLE(media),
2699     ADD_TABLE(property)
2700 };
2701
2702 static const msi_table sr_tables[] =
2703 {
2704     ADD_TABLE(component),
2705     ADD_TABLE(directory),
2706     ADD_TABLE(feature),
2707     ADD_TABLE(feature_comp),
2708     ADD_TABLE(file),
2709     ADD_TABLE(sr_selfreg),
2710     ADD_TABLE(sr_install_exec_seq),
2711     ADD_TABLE(media),
2712     ADD_TABLE(property)
2713 };
2714
2715 static const msi_table font_tables[] =
2716 {
2717     ADD_TABLE(font_component),
2718     ADD_TABLE(directory),
2719     ADD_TABLE(font_feature),
2720     ADD_TABLE(font_feature_comp),
2721     ADD_TABLE(font_file),
2722     ADD_TABLE(font),
2723     ADD_TABLE(font_install_exec_seq),
2724     ADD_TABLE(font_media),
2725     ADD_TABLE(property)
2726 };
2727
2728 static const msi_table vp_tables[] =
2729 {
2730     ADD_TABLE(component),
2731     ADD_TABLE(directory),
2732     ADD_TABLE(feature),
2733     ADD_TABLE(feature_comp),
2734     ADD_TABLE(file),
2735     ADD_TABLE(vp_custom_action),
2736     ADD_TABLE(vp_install_exec_seq),
2737     ADD_TABLE(media),
2738     ADD_TABLE(vp_property)
2739 };
2740
2741 static const msi_table odbc_tables[] =
2742 {
2743     ADD_TABLE(odbc_component),
2744     ADD_TABLE(directory),
2745     ADD_TABLE(odbc_feature),
2746     ADD_TABLE(odbc_feature_comp),
2747     ADD_TABLE(odbc_file),
2748     ADD_TABLE(odbc_driver),
2749     ADD_TABLE(odbc_translator),
2750     ADD_TABLE(odbc_datasource),
2751     ADD_TABLE(odbc_install_exec_seq),
2752     ADD_TABLE(odbc_media),
2753     ADD_TABLE(property)
2754 };
2755
2756 static const msi_table tl_tables[] =
2757 {
2758     ADD_TABLE(tl_component),
2759     ADD_TABLE(directory),
2760     ADD_TABLE(tl_feature),
2761     ADD_TABLE(tl_feature_comp),
2762     ADD_TABLE(tl_file),
2763     ADD_TABLE(tl_typelib),
2764     ADD_TABLE(tl_install_exec_seq),
2765     ADD_TABLE(media),
2766     ADD_TABLE(property)
2767 };
2768
2769 static const msi_table crs_tables[] =
2770 {
2771     ADD_TABLE(crs_component),
2772     ADD_TABLE(directory),
2773     ADD_TABLE(crs_feature),
2774     ADD_TABLE(crs_feature_comp),
2775     ADD_TABLE(crs_file),
2776     ADD_TABLE(crs_shortcut),
2777     ADD_TABLE(crs_install_exec_seq),
2778     ADD_TABLE(media),
2779     ADD_TABLE(property)
2780 };
2781
2782 static const msi_table pub_tables[] =
2783 {
2784     ADD_TABLE(directory),
2785     ADD_TABLE(pub_component),
2786     ADD_TABLE(pub_feature),
2787     ADD_TABLE(pub_feature_comp),
2788     ADD_TABLE(pub_file),
2789     ADD_TABLE(pub_publish_component),
2790     ADD_TABLE(pub_install_exec_seq),
2791     ADD_TABLE(media),
2792     ADD_TABLE(property)
2793 };
2794
2795 static const msi_table rd_tables[] =
2796 {
2797     ADD_TABLE(directory),
2798     ADD_TABLE(rd_component),
2799     ADD_TABLE(rd_feature),
2800     ADD_TABLE(rd_feature_comp),
2801     ADD_TABLE(rd_file),
2802     ADD_TABLE(rd_duplicate_file),
2803     ADD_TABLE(rd_install_exec_seq),
2804     ADD_TABLE(media),
2805     ADD_TABLE(property)
2806 };
2807
2808 static const msi_table rrv_tables[] =
2809 {
2810     ADD_TABLE(directory),
2811     ADD_TABLE(rrv_component),
2812     ADD_TABLE(rrv_feature),
2813     ADD_TABLE(rrv_feature_comp),
2814     ADD_TABLE(rrv_file),
2815     ADD_TABLE(rrv_registry),
2816     ADD_TABLE(rrv_remove_registry),
2817     ADD_TABLE(rrv_install_exec_seq),
2818     ADD_TABLE(media),
2819     ADD_TABLE(property)
2820 };
2821
2822 static const msi_table frp_tables[] =
2823 {
2824     ADD_TABLE(directory),
2825     ADD_TABLE(frp_component),
2826     ADD_TABLE(frp_feature),
2827     ADD_TABLE(frp_feature_comp),
2828     ADD_TABLE(frp_file),
2829     ADD_TABLE(frp_upgrade),
2830     ADD_TABLE(frp_custom_action),
2831     ADD_TABLE(frp_install_exec_seq),
2832     ADD_TABLE(media),
2833     ADD_TABLE(property)
2834 };
2835
2836 static const msi_table riv_tables[] =
2837 {
2838     ADD_TABLE(directory),
2839     ADD_TABLE(riv_component),
2840     ADD_TABLE(riv_feature),
2841     ADD_TABLE(riv_feature_comp),
2842     ADD_TABLE(riv_file),
2843     ADD_TABLE(riv_ini_file),
2844     ADD_TABLE(riv_remove_ini_file),
2845     ADD_TABLE(riv_install_exec_seq),
2846     ADD_TABLE(media),
2847     ADD_TABLE(property)
2848 };
2849
2850 static const msi_table res_tables[] =
2851 {
2852     ADD_TABLE(directory),
2853     ADD_TABLE(res_component),
2854     ADD_TABLE(res_feature),
2855     ADD_TABLE(res_feature_comp),
2856     ADD_TABLE(res_file),
2857     ADD_TABLE(res_environment),
2858     ADD_TABLE(res_install_exec_seq),
2859     ADD_TABLE(media),
2860     ADD_TABLE(property)
2861 };
2862
2863 static const msi_table rci_tables[] =
2864 {
2865     ADD_TABLE(directory),
2866     ADD_TABLE(rci_component),
2867     ADD_TABLE(rci_feature),
2868     ADD_TABLE(rci_feature_comp),
2869     ADD_TABLE(rci_file),
2870     ADD_TABLE(rci_appid),
2871     ADD_TABLE(rci_class),
2872     ADD_TABLE(rci_install_exec_seq),
2873     ADD_TABLE(media),
2874     ADD_TABLE(property)
2875 };
2876
2877 static const msi_table rei_tables[] =
2878 {
2879     ADD_TABLE(directory),
2880     ADD_TABLE(rei_component),
2881     ADD_TABLE(rei_feature),
2882     ADD_TABLE(rei_feature_comp),
2883     ADD_TABLE(rei_file),
2884     ADD_TABLE(rei_extension),
2885     ADD_TABLE(rei_verb),
2886     ADD_TABLE(rei_progid),
2887     ADD_TABLE(rei_install_exec_seq),
2888     ADD_TABLE(media),
2889     ADD_TABLE(property)
2890 };
2891
2892 static const msi_table rmi_tables[] =
2893 {
2894     ADD_TABLE(directory),
2895     ADD_TABLE(rmi_component),
2896     ADD_TABLE(rmi_feature),
2897     ADD_TABLE(rmi_feature_comp),
2898     ADD_TABLE(rmi_file),
2899     ADD_TABLE(rmi_extension),
2900     ADD_TABLE(rmi_verb),
2901     ADD_TABLE(rmi_mime),
2902     ADD_TABLE(rmi_install_exec_seq),
2903     ADD_TABLE(media),
2904     ADD_TABLE(property)
2905 };
2906
2907 static const msi_table fo_tables[] =
2908 {
2909     ADD_TABLE(directory),
2910     ADD_TABLE(fo_file),
2911     ADD_TABLE(fo_component),
2912     ADD_TABLE(fo_feature),
2913     ADD_TABLE(fo_condition),
2914     ADD_TABLE(fo_feature_comp),
2915     ADD_TABLE(fo_custom_action),
2916     ADD_TABLE(fo_install_exec_seq),
2917     ADD_TABLE(media),
2918     ADD_TABLE(property)
2919 };
2920
2921 static const msi_table icon_base_tables[] =
2922 {
2923     ADD_TABLE(ci_component),
2924     ADD_TABLE(directory),
2925     ADD_TABLE(rof_feature),
2926     ADD_TABLE(rof_feature_comp),
2927     ADD_TABLE(rof_file),
2928     ADD_TABLE(pp_install_exec_seq),
2929     ADD_TABLE(rof_media),
2930     ADD_TABLE(icon_property),
2931 };
2932
2933 /* cabinet definitions */
2934
2935 /* make the max size large so there is only one cab file */
2936 #define MEDIA_SIZE          0x7FFFFFFF
2937 #define FOLDER_THRESHOLD    900000
2938
2939 /* the FCI callbacks */
2940
2941 static void * CDECL mem_alloc(ULONG cb)
2942 {
2943     return HeapAlloc(GetProcessHeap(), 0, cb);
2944 }
2945
2946 static void CDECL mem_free(void *memory)
2947 {
2948     HeapFree(GetProcessHeap(), 0, memory);
2949 }
2950
2951 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
2952 {
2953     sprintf(pccab->szCab, pv, pccab->iCab);
2954     return TRUE;
2955 }
2956
2957 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
2958 {
2959     return 0;
2960 }
2961
2962 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
2963                              BOOL fContinuation, void *pv)
2964 {
2965     return 0;
2966 }
2967
2968 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
2969 {
2970     HANDLE handle;
2971     DWORD dwAccess = 0;
2972     DWORD dwShareMode = 0;
2973     DWORD dwCreateDisposition = OPEN_EXISTING;
2974     
2975     dwAccess = GENERIC_READ | GENERIC_WRITE;
2976     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
2977     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
2978
2979     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
2980         dwCreateDisposition = OPEN_EXISTING;
2981     else
2982         dwCreateDisposition = CREATE_NEW;
2983
2984     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
2985                          dwCreateDisposition, 0, NULL);
2986
2987     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
2988
2989     return (INT_PTR)handle;
2990 }
2991
2992 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2993 {
2994     HANDLE handle = (HANDLE)hf;
2995     DWORD dwRead;
2996     BOOL res;
2997     
2998     res = ReadFile(handle, memory, cb, &dwRead, NULL);
2999     ok(res, "Failed to ReadFile\n");
3000
3001     return dwRead;
3002 }
3003
3004 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
3005 {
3006     HANDLE handle = (HANDLE)hf;
3007     DWORD dwWritten;
3008     BOOL res;
3009
3010     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
3011     ok(res, "Failed to WriteFile\n");
3012
3013     return dwWritten;
3014 }
3015
3016 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
3017 {
3018     HANDLE handle = (HANDLE)hf;
3019     ok(CloseHandle(handle), "Failed to CloseHandle\n");
3020
3021     return 0;
3022 }
3023
3024 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
3025 {
3026     HANDLE handle = (HANDLE)hf;
3027     DWORD ret;
3028     
3029     ret = SetFilePointer(handle, dist, NULL, seektype);
3030     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
3031
3032     return ret;
3033 }
3034
3035 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
3036 {
3037     BOOL ret = DeleteFileA(pszFile);
3038     ok(ret, "Failed to DeleteFile %s\n", pszFile);
3039
3040     return 0;
3041 }
3042
3043 static void init_functionpointers(void)
3044 {
3045     HMODULE hmsi = GetModuleHandleA("msi.dll");
3046     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
3047
3048 #define GET_PROC(mod, func) \
3049     p ## func = (void*)GetProcAddress(mod, #func); \
3050     if(!p ## func) \
3051       trace("GetProcAddress(%s) failed\n", #func);
3052
3053     GET_PROC(hmsi, MsiQueryComponentStateA);
3054     GET_PROC(hmsi, MsiSetExternalUIRecord);
3055     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
3056     GET_PROC(hmsi, MsiSourceListGetInfoA);
3057
3058     GET_PROC(hadvapi32, ConvertSidToStringSidA);
3059
3060     hsrclient = LoadLibraryA("srclient.dll");
3061     GET_PROC(hsrclient, SRRemoveRestorePoint);
3062     GET_PROC(hsrclient, SRSetRestorePointA);
3063
3064 #undef GET_PROC
3065 }
3066
3067 static BOOL check_win9x(void)
3068 {
3069     SC_HANDLE scm;
3070
3071     scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
3072     if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3073         return TRUE;
3074
3075     CloseServiceHandle(scm);
3076
3077     return FALSE;
3078 }
3079
3080 static LPSTR get_user_sid(LPSTR *usersid)
3081 {
3082     HANDLE token;
3083     BYTE buf[1024];
3084     DWORD size;
3085     PTOKEN_USER user;
3086
3087     if (!pConvertSidToStringSidA)
3088     {
3089         win_skip("ConvertSidToStringSidA is not available\n");
3090         return NULL;
3091     }
3092
3093     *usersid = NULL;
3094     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
3095     size = sizeof(buf);
3096     GetTokenInformation(token, TokenUser, buf, size, &size);
3097     user = (PTOKEN_USER)buf;
3098     pConvertSidToStringSidA(user->User.Sid, usersid);
3099     ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError());
3100     CloseHandle(token);
3101     return *usersid;
3102 }
3103
3104 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
3105 {
3106     CHAR buffer[0x20];
3107     UINT r;
3108     DWORD sz;
3109
3110     sz = sizeof buffer;
3111     r = MsiRecordGetString(rec, field, buffer, &sz);
3112     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
3113 }
3114
3115 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
3116 {
3117     LPSTR tempname;
3118
3119     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3120     GetTempFileNameA(".", "xx", 0, tempname);
3121
3122     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
3123     {
3124         lstrcpyA(pszTempName, tempname);
3125         HeapFree(GetProcessHeap(), 0, tempname);
3126         return TRUE;
3127     }
3128
3129     HeapFree(GetProcessHeap(), 0, tempname);
3130
3131     return FALSE;
3132 }
3133
3134 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
3135                                    USHORT *pattribs, int *err, void *pv)
3136 {
3137     BY_HANDLE_FILE_INFORMATION finfo;
3138     FILETIME filetime;
3139     HANDLE handle;
3140     DWORD attrs;
3141     BOOL res;
3142
3143     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
3144                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
3145
3146     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
3147
3148     res = GetFileInformationByHandle(handle, &finfo);
3149     ok(res, "Expected GetFileInformationByHandle to succeed\n");
3150    
3151     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
3152     FileTimeToDosDateTime(&filetime, pdate, ptime);
3153
3154     attrs = GetFileAttributes(pszName);
3155     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
3156
3157     return (INT_PTR)handle;
3158 }
3159
3160 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
3161 {
3162     char path[MAX_PATH];
3163     char filename[MAX_PATH];
3164
3165     lstrcpyA(path, CURR_DIR);
3166     lstrcatA(path, "\\");
3167     lstrcatA(path, file);
3168
3169     lstrcpyA(filename, file);
3170
3171     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
3172                       progress, get_open_info, compress);
3173 }
3174
3175 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
3176 {
3177     ZeroMemory(pCabParams, sizeof(CCAB));
3178
3179     pCabParams->cb = max_size;
3180     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
3181     pCabParams->setID = 0xbeef;
3182     pCabParams->iCab = 1;
3183     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
3184     lstrcatA(pCabParams->szCabPath, "\\");
3185     lstrcpyA(pCabParams->szCab, name);
3186 }
3187
3188 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
3189 {
3190     CCAB cabParams;
3191     LPCSTR ptr;
3192     HFCI hfci;
3193     ERF erf;
3194     BOOL res;
3195
3196     set_cab_parameters(&cabParams, name, max_size);
3197
3198     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
3199                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
3200                       get_temp_file, &cabParams, NULL);
3201
3202     ok(hfci != NULL, "Failed to create an FCI context\n");
3203
3204     ptr = files;
3205     while (*ptr)
3206     {
3207         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
3208         ok(res, "Failed to add file: %s\n", ptr);
3209         ptr += lstrlen(ptr) + 1;
3210     }
3211
3212     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
3213     ok(res, "Failed to flush the cabinet\n");
3214
3215     res = FCIDestroy(hfci);
3216     ok(res, "Failed to destroy the cabinet\n");
3217 }
3218
3219 static BOOL get_user_dirs(void)
3220 {
3221     HKEY hkey;
3222     DWORD type, size;
3223
3224     if(RegOpenKey(HKEY_CURRENT_USER,
3225                    "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
3226                    &hkey))
3227         return FALSE;
3228
3229     size = MAX_PATH;
3230     if(RegQueryValueExA(hkey, "AppData", 0, &type, (LPBYTE)APP_DATA_DIR, &size)){
3231         RegCloseKey(hkey);
3232         return FALSE;
3233     }
3234
3235     RegCloseKey(hkey);
3236     return TRUE;
3237 }
3238
3239 static BOOL get_system_dirs(void)
3240 {
3241     HKEY hkey;
3242     DWORD type, size;
3243
3244     if (RegOpenKey(HKEY_LOCAL_MACHINE,
3245                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
3246         return FALSE;
3247
3248     size = MAX_PATH;
3249     if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
3250         RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size)) {
3251         RegCloseKey(hkey);
3252         return FALSE;
3253     }
3254
3255     size = MAX_PATH;
3256     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size)) {
3257         RegCloseKey(hkey);
3258         return FALSE;
3259     }
3260
3261     RegCloseKey(hkey);
3262
3263     if(GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH) != ERROR_SUCCESS)
3264         return FALSE;
3265
3266     return TRUE;
3267 }
3268
3269 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
3270 {
3271     HANDLE file;
3272     DWORD written;
3273
3274     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
3275     if (file == INVALID_HANDLE_VALUE)
3276         return;
3277
3278     WriteFile(file, data, strlen(data), &written, NULL);
3279
3280     if (size)
3281     {
3282         SetFilePointer(file, size, NULL, FILE_BEGIN);
3283         SetEndOfFile(file);
3284     }
3285
3286     CloseHandle(file);
3287 }
3288
3289 #define create_file(name, size) create_file_data(name, name, size)
3290
3291 static void create_test_files(void)
3292 {
3293     CreateDirectoryA("msitest", NULL);
3294     create_file("msitest\\one.txt", 100);
3295     CreateDirectoryA("msitest\\first", NULL);
3296     create_file("msitest\\first\\two.txt", 100);
3297     CreateDirectoryA("msitest\\second", NULL);
3298     create_file("msitest\\second\\three.txt", 100);
3299
3300     create_file("four.txt", 100);
3301     create_file("five.txt", 100);
3302     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
3303
3304     create_file("msitest\\filename", 100);
3305     create_file("msitest\\service.exe", 100);
3306
3307     DeleteFileA("four.txt");
3308     DeleteFileA("five.txt");
3309 }
3310
3311 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
3312 {
3313     CHAR path[MAX_PATH];
3314
3315     lstrcpyA(path, PROG_FILES_DIR);
3316     lstrcatA(path, "\\");
3317     lstrcatA(path, rel_path);
3318
3319     if (is_file)
3320         return DeleteFileA(path);
3321     else
3322         return RemoveDirectoryA(path);
3323 }
3324
3325 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
3326 {
3327     CHAR path[MAX_PATH];
3328
3329     lstrcpyA(path, COMMON_FILES_DIR);
3330     lstrcatA(path, "\\");
3331     lstrcatA(path, rel_path);
3332
3333     if (is_file)
3334         return DeleteFileA(path);
3335     else
3336         return RemoveDirectoryA(path);
3337 }
3338
3339 static void delete_test_files(void)
3340 {
3341     DeleteFileA("msitest.msi");
3342     DeleteFileA("msitest.cab");
3343     DeleteFileA("msitest\\second\\three.txt");
3344     DeleteFileA("msitest\\first\\two.txt");
3345     DeleteFileA("msitest\\one.txt");
3346     DeleteFileA("msitest\\service.exe");
3347     DeleteFileA("msitest\\filename");
3348     RemoveDirectoryA("msitest\\second");
3349     RemoveDirectoryA("msitest\\first");
3350     RemoveDirectoryA("msitest");
3351 }
3352
3353 static void write_file(const CHAR *filename, const char *data, int data_size)
3354 {
3355     DWORD size;
3356
3357     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
3358                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3359
3360     WriteFile(hf, data, data_size, &size, NULL);
3361     CloseHandle(hf);
3362 }
3363
3364 static void write_msi_summary_info(MSIHANDLE db, INT wordcount)
3365 {
3366     MSIHANDLE summary;
3367     UINT r;
3368
3369     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
3370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3371
3372     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
3373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3374
3375     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3376                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
3377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3378
3379     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3380     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3381
3382     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
3383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3384
3385     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3387
3388     /* write the summary changes back to the stream */
3389     r = MsiSummaryInfoPersist(summary);
3390     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3391
3392     MsiCloseHandle(summary);
3393 }
3394
3395 #define create_database(name, tables, num_tables) \
3396     create_database_wordcount(name, tables, num_tables, 0);
3397
3398 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
3399                                       int num_tables, INT wordcount)
3400 {
3401     MSIHANDLE db;
3402     UINT r;
3403     int j;
3404
3405     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
3406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3407
3408     /* import the tables into the database */
3409     for (j = 0; j < num_tables; j++)
3410     {
3411         const msi_table *table = &tables[j];
3412
3413         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
3414
3415         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
3416         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3417
3418         DeleteFileA(table->filename);
3419     }
3420
3421     write_msi_summary_info(db, wordcount);
3422
3423     r = MsiDatabaseCommit(db);
3424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3425
3426     MsiCloseHandle(db);
3427 }
3428
3429 static void check_service_is_installed(void)
3430 {
3431     SC_HANDLE scm, service;
3432     BOOL res;
3433
3434     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
3435     ok(scm != NULL, "Failed to open the SC Manager\n");
3436
3437     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
3438     ok(service != NULL, "Failed to open TestService\n");
3439
3440     res = DeleteService(service);
3441     ok(res, "Failed to delete TestService\n");
3442
3443     CloseServiceHandle(service);
3444     CloseServiceHandle(scm);
3445 }
3446
3447 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
3448 {
3449     RESTOREPOINTINFOA spec;
3450
3451     spec.dwEventType = event_type;
3452     spec.dwRestorePtType = APPLICATION_INSTALL;
3453     spec.llSequenceNumber = status->llSequenceNumber;
3454     lstrcpyA(spec.szDescription, "msitest restore point");
3455
3456     return pSRSetRestorePointA(&spec, status);
3457 }
3458
3459 static void remove_restore_point(DWORD seq_number)
3460 {
3461     DWORD res;
3462
3463     res = pSRRemoveRestorePoint(seq_number);
3464     if (res != ERROR_SUCCESS)
3465         trace("Failed to remove the restore point : %08x\n", res);
3466 }
3467
3468 static void test_MsiInstallProduct(void)
3469 {
3470     UINT r;
3471     CHAR path[MAX_PATH];
3472     LONG res;
3473     HKEY hkey;
3474     DWORD num, size, type;
3475
3476     if (on_win9x)
3477     {
3478         win_skip("Services are not implemented on Win9x and WinMe\n");
3479         return;
3480     }
3481
3482     /* szPackagePath is NULL */
3483     r = MsiInstallProductA(NULL, "INSTALL=ALL");
3484     ok(r == ERROR_INVALID_PARAMETER,
3485        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3486
3487     /* both szPackagePath and szCommandLine are NULL */
3488     r = MsiInstallProductA(NULL, NULL);
3489     ok(r == ERROR_INVALID_PARAMETER,
3490        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3491
3492     /* szPackagePath is empty */
3493     r = MsiInstallProductA("", "INSTALL=ALL");
3494     ok(r == ERROR_PATH_NOT_FOUND,
3495        "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
3496
3497     create_test_files();
3498     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3499
3500     /* install, don't publish */
3501     r = MsiInstallProductA(msifile, NULL);
3502     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3503
3504     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3505     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3506     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3507     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3508     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3509     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3510     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3511     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3512     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3513     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3514     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3515     ok(delete_pf("msitest", FALSE), "File not installed\n");
3516
3517     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3518     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3519
3520     size = MAX_PATH;
3521     type = REG_SZ;
3522     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
3523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3524     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
3525
3526     size = MAX_PATH;
3527     type = REG_SZ;
3528     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
3529     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3530
3531     size = sizeof(num);
3532     type = REG_DWORD;
3533     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
3534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3535     ok(num == 314, "Expected 314, got %d\n", num);
3536
3537     size = MAX_PATH;
3538     type = REG_SZ;
3539     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
3540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3541     ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
3542
3543     check_service_is_installed();
3544
3545     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3546
3547     /* not published, reinstall */
3548     r = MsiInstallProductA(msifile, NULL);
3549     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3550
3551     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3552     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3553     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3554     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3555     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3556     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3557     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3558     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3559     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3560     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3561     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3562     ok(delete_pf("msitest", FALSE), "File not installed\n");
3563
3564     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3566     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3567
3568     create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table));
3569
3570     /* not published, RemovePreviousVersions set */
3571     r = MsiInstallProductA(msifile, NULL);
3572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3573
3574     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3575     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3576     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3577     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3578     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3579     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3580     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3581     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3582     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3583     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3584     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3585     ok(delete_pf("msitest", FALSE), "File not installed\n");
3586
3587     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3589     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3590
3591     create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table));
3592
3593     /* not published, version number bumped */
3594     r = MsiInstallProductA(msifile, NULL);
3595     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3596
3597     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3598     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3599     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3600     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3601     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3602     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3603     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3604     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3605     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3606     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3607     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3608     ok(delete_pf("msitest", FALSE), "File not installed\n");
3609
3610     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3612     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3613
3614     create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table));
3615
3616     /* not published, RemovePreviousVersions set and version number bumped */
3617     r = MsiInstallProductA(msifile, NULL);
3618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3619
3620     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3621     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3622     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3623     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3624     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3625     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3626     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3627     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3628     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3629     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3630     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3631     ok(delete_pf("msitest", FALSE), "File not installed\n");
3632
3633     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3635     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3636
3637     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3638
3639     /* install, publish product */
3640     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3641     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3642
3643     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3644     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3645     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3646     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3647     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3648     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3649     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3650     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3651     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3652     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3653     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3654     ok(delete_pf("msitest", FALSE), "File not installed\n");
3655
3656     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3657     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3658
3659     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3660
3661     /* published, reinstall */
3662     r = MsiInstallProductA(msifile, NULL);
3663     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3664
3665     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3666     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3667     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3668     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3669     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3670     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3671     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3672     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3673     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3674     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3675     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3676     ok(delete_pf("msitest", FALSE), "File not installed\n");
3677
3678     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3679     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3680
3681     create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table));
3682
3683     /* published product, RemovePreviousVersions set */
3684     r = MsiInstallProductA(msifile, NULL);
3685     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3686
3687     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3688     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3689     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3690     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3691     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3692     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3693     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3694     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3695     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3696     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3697     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3698     ok(delete_pf("msitest", FALSE), "File not installed\n");
3699
3700     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3701     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3702
3703     create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table));
3704
3705     /* published product, version number bumped */
3706     r = MsiInstallProductA(msifile, NULL);
3707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3708
3709     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3710     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3711     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3712     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3713     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3714     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3715     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3716     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3717     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3718     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3719     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3720     ok(delete_pf("msitest", FALSE), "File not installed\n");
3721
3722     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3723     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3724
3725     create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table));
3726
3727     /* published product, RemovePreviousVersions set and version number bumped */
3728     r = MsiInstallProductA(msifile, NULL);
3729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3730
3731     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3732     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3733     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3734     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3735     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3736     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3737     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3738     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3739     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3740     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3741     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3742     ok(delete_pf("msitest", FALSE), "File not installed\n");
3743
3744     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3745     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3746
3747     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3749
3750     delete_test_files();
3751 }
3752
3753 static void test_MsiSetComponentState(void)
3754 {
3755     INSTALLSTATE installed, action;
3756     MSIHANDLE package;
3757     char path[MAX_PATH];
3758     UINT r;
3759
3760     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3761
3762     CoInitialize(NULL);
3763
3764     lstrcpy(path, CURR_DIR);
3765     lstrcat(path, "\\");
3766     lstrcat(path, msifile);
3767
3768     r = MsiOpenPackage(path, &package);
3769     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3770
3771     r = MsiDoAction(package, "CostInitialize");
3772     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3773
3774     r = MsiDoAction(package, "FileCost");
3775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3776
3777     r = MsiDoAction(package, "CostFinalize");
3778     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3779
3780     r = MsiGetComponentState(package, "dangler", &installed, &action);
3781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3782     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
3783     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
3784
3785     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
3786     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3787
3788     MsiCloseHandle(package);
3789     CoUninitialize();
3790
3791     DeleteFileA(msifile);
3792 }
3793
3794 static void test_packagecoltypes(void)
3795 {
3796     MSIHANDLE hdb, view, rec;
3797     char path[MAX_PATH];
3798     LPCSTR query;
3799     UINT r, count;
3800
3801     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3802
3803     CoInitialize(NULL);
3804
3805     lstrcpy(path, CURR_DIR);
3806     lstrcat(path, "\\");
3807     lstrcat(path, msifile);
3808
3809     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
3810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3811
3812     query = "SELECT * FROM `Media`";
3813     r = MsiDatabaseOpenView( hdb, query, &view );
3814     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3815
3816     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
3817     count = MsiRecordGetFieldCount( rec );
3818     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3819     ok(count == 6, "Expected 6, got %d\n", count);
3820     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
3821     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
3822     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
3823     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
3824     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
3825     ok(check_record(rec, 6, "Source"), "wrong column label\n");
3826     MsiCloseHandle(rec);
3827
3828     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
3829     count = MsiRecordGetFieldCount( rec );
3830     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3831     ok(count == 6, "Expected 6, got %d\n", count);
3832     ok(check_record(rec, 1, "i2"), "wrong column label\n");
3833     ok(check_record(rec, 2, "i4"), "wrong column label\n");
3834     ok(check_record(rec, 3, "L64"), "wrong column label\n");
3835     ok(check_record(rec, 4, "S255"), "wrong column label\n");
3836     ok(check_record(rec, 5, "S32"), "wrong column label\n");
3837     ok(check_record(rec, 6, "S72"), "wrong column label\n");
3838
3839     MsiCloseHandle(rec);
3840     MsiCloseHandle(view);
3841     MsiCloseHandle(hdb);
3842     CoUninitialize();
3843
3844     DeleteFile(msifile);
3845 }
3846
3847 static void create_cc_test_files(void)
3848 {
3849     CCAB cabParams;
3850     HFCI hfci;
3851     ERF erf;
3852     static CHAR cab_context[] = "test%d.cab";
3853     BOOL res;
3854
3855     create_file("maximus", 500);
3856     create_file("augustus", 50000);
3857     create_file("tiberius", 500);
3858     create_file("caesar", 500);
3859
3860     set_cab_parameters(&cabParams, "test1.cab", 40000);
3861
3862     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
3863                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
3864                       get_temp_file, &cabParams, cab_context);
3865     ok(hfci != NULL, "Failed to create an FCI context\n");
3866
3867     res = add_file(hfci, "maximus", tcompTYPE_NONE);
3868     ok(res, "Failed to add file maximus\n");
3869
3870     res = add_file(hfci, "augustus", tcompTYPE_NONE);
3871     ok(res, "Failed to add file augustus\n");
3872
3873     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
3874     ok(res, "Failed to add file tiberius\n");
3875
3876     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
3877     ok(res, "Failed to flush the cabinet\n");
3878
3879     res = FCIDestroy(hfci);
3880     ok(res, "Failed to destroy the cabinet\n");
3881
3882     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3883
3884     DeleteFile("maximus");
3885     DeleteFile("augustus");
3886     DeleteFile("tiberius");
3887     DeleteFile("caesar");
3888 }
3889
3890 static void delete_cab_files(void)
3891 {
3892     SHFILEOPSTRUCT shfl;
3893     CHAR path[MAX_PATH+10];
3894
3895     lstrcpyA(path, CURR_DIR);
3896     lstrcatA(path, "\\*.cab");
3897     path[strlen(path) + 1] = '\0';
3898
3899     shfl.hwnd = NULL;
3900     shfl.wFunc = FO_DELETE;
3901     shfl.pFrom = path;
3902     shfl.pTo = NULL;
3903     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
3904
3905     SHFileOperation(&shfl);
3906 }
3907
3908 static void test_continuouscabs(void)
3909 {
3910     UINT r;
3911
3912     create_cc_test_files();
3913     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3914
3915     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3916
3917     r = MsiInstallProductA(msifile, NULL);
3918     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3919     {
3920         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3921         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3922         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3923         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3924         ok(delete_pf("msitest", FALSE), "File not installed\n");
3925     }
3926
3927     delete_cab_files();
3928     DeleteFile(msifile);
3929
3930     create_cc_test_files();
3931     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
3932
3933     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3934
3935     r = MsiInstallProductA(msifile, NULL);
3936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3937     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3938     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3939     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
3940     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3941     ok(delete_pf("msitest", FALSE), "File not installed\n");
3942
3943     delete_cab_files();
3944     DeleteFile(msifile);
3945 }
3946
3947 static void test_caborder(void)
3948 {
3949     UINT r;
3950
3951     create_file("imperator", 100);
3952     create_file("maximus", 500);
3953     create_file("augustus", 50000);
3954     create_file("caesar", 500);
3955
3956     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3957
3958     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3959
3960     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3961     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3962     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3963
3964     r = MsiInstallProductA(msifile, NULL);
3965     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3966     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3967     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3968     todo_wine
3969     {
3970         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3971         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3972     }
3973
3974     delete_cab_files();
3975
3976     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
3977     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
3978     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3979
3980     r = MsiInstallProductA(msifile, NULL);
3981     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3982     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3983     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3984     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3985     ok(!delete_pf("msitest", FALSE), "File is installed\n");
3986
3987     delete_cab_files();
3988     DeleteFile(msifile);
3989
3990     create_cc_test_files();
3991     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
3992
3993     r = MsiInstallProductA(msifile, NULL);
3994     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3995     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3996     ok(!delete_pf("msitest", FALSE), "File is installed\n");
3997     todo_wine
3998     {
3999         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
4000         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
4001     }
4002
4003     delete_cab_files();
4004     DeleteFile(msifile);
4005
4006     create_cc_test_files();
4007     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
4008
4009     r = MsiInstallProductA(msifile, NULL);
4010     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
4011     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4012     todo_wine
4013     {
4014         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
4015         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
4016         ok(!delete_pf("msitest", FALSE), "File is installed\n");
4017     }
4018
4019     delete_cab_files();
4020     DeleteFile("imperator");
4021     DeleteFile("maximus");
4022     DeleteFile("augustus");
4023     DeleteFile("caesar");
4024     DeleteFile(msifile);
4025 }
4026
4027 static void test_mixedmedia(void)
4028 {
4029     UINT r;
4030
4031     CreateDirectoryA("msitest", NULL);
4032     create_file("msitest\\maximus", 500);
4033     create_file("msitest\\augustus", 500);
4034     create_file("caesar", 500);
4035
4036     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
4037
4038     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4039
4040     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
4041
4042     r = MsiInstallProductA(msifile, NULL);
4043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4044     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4045     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4046     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4047     ok(delete_pf("msitest", FALSE), "File not installed\n");
4048
4049     /* Delete the files in the temp (current) folder */
4050     DeleteFile("msitest\\maximus");
4051     DeleteFile("msitest\\augustus");
4052     RemoveDirectory("msitest");
4053     DeleteFile("caesar");
4054     DeleteFile("test1.cab");
4055     DeleteFile(msifile);
4056 }
4057
4058 static void test_samesequence(void)
4059 {
4060     UINT r;
4061
4062     create_cc_test_files();
4063     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
4064
4065     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4066
4067     r = MsiInstallProductA(msifile, NULL);
4068     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
4069     {
4070         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4071         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4072         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4073         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4074         ok(delete_pf("msitest", FALSE), "File not installed\n");
4075     }
4076
4077     delete_cab_files();
4078     DeleteFile(msifile);
4079 }
4080
4081 static void test_uiLevelFlags(void)
4082 {
4083     UINT r;
4084
4085     create_cc_test_files();
4086     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
4087
4088     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
4089
4090     r = MsiInstallProductA(msifile, NULL);
4091     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
4092     {
4093         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4094         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
4095         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4096         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4097         ok(delete_pf("msitest", FALSE), "File not installed\n");
4098     }
4099
4100     delete_cab_files();
4101     DeleteFile(msifile);
4102 }
4103
4104 static BOOL file_matches(LPSTR path)
4105 {
4106     CHAR buf[MAX_PATH];
4107     HANDLE file;
4108     DWORD size;
4109
4110     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4111                       NULL, OPEN_EXISTING, 0, NULL);
4112
4113     ZeroMemory(buf, MAX_PATH);
4114     ReadFile(file, buf, 15, &size, NULL);
4115     CloseHandle(file);
4116
4117     return !lstrcmp(buf, "msitest\\maximus");
4118 }
4119
4120 static void test_readonlyfile(void)
4121 {
4122     UINT r;
4123     DWORD size;
4124     HANDLE file;
4125     CHAR path[MAX_PATH];
4126
4127     CreateDirectoryA("msitest", NULL);
4128     create_file("msitest\\maximus", 500);
4129     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
4130
4131     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4132
4133     lstrcpy(path, PROG_FILES_DIR);
4134     lstrcat(path, "\\msitest");
4135     CreateDirectory(path, NULL);
4136
4137     lstrcat(path, "\\maximus");
4138     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4139                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
4140
4141     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
4142     CloseHandle(file);
4143
4144     r = MsiInstallProductA(msifile, NULL);
4145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4146     ok(file_matches(path), "Expected file to be overwritten\n");
4147     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4148     ok(delete_pf("msitest", FALSE), "File not installed\n");
4149
4150     /* Delete the files in the temp (current) folder */
4151     DeleteFile("msitest\\maximus");
4152     RemoveDirectory("msitest");
4153     DeleteFile(msifile);
4154 }
4155
4156 static void test_readonlyfile_cab(void)
4157 {
4158     UINT r;
4159     DWORD size;
4160     HANDLE file;
4161     CHAR path[MAX_PATH];
4162     CHAR buf[16];
4163
4164     CreateDirectoryA("msitest", NULL);
4165     create_file("maximus", 500);
4166     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4167     DeleteFile("maximus");
4168
4169     create_database(msifile, rofc_tables, sizeof(rofc_tables) / sizeof(msi_table));
4170
4171     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4172
4173     lstrcpy(path, PROG_FILES_DIR);
4174     lstrcat(path, "\\msitest");
4175     CreateDirectory(path, NULL);
4176
4177     lstrcat(path, "\\maximus");
4178     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4179                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
4180
4181     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
4182     CloseHandle(file);
4183
4184     r = MsiInstallProductA(msifile, NULL);
4185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4186
4187     memset( buf, 0, sizeof(buf) );
4188     if ((file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4189                            NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
4190     {
4191         ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
4192         CloseHandle(file);
4193     }
4194     ok(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "Expected file to be overwritten, got '%s'\n", buf);
4195     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4196     ok(delete_pf("msitest", FALSE), "File not installed\n");
4197
4198     /* Delete the files in the temp (current) folder */
4199     delete_cab_files();
4200     DeleteFile("msitest\\maximus");
4201     RemoveDirectory("msitest");
4202     DeleteFile(msifile);
4203 }
4204
4205 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
4206 {
4207     WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
4208     IStorage *stg;
4209     IStream *stm;
4210     HRESULT hr;
4211     HANDLE handle;
4212
4213     MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
4214     hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
4215     if (FAILED(hr))
4216         return FALSE;
4217
4218     MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
4219     hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4220     if (FAILED(hr))
4221     {
4222         IStorage_Release(stg);
4223         return FALSE;
4224     }
4225
4226     handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
4227     if (handle != INVALID_HANDLE_VALUE)
4228     {
4229         DWORD count;
4230         char buffer[1024];
4231         if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
4232             IStream_Write(stm, buffer, count, &count);
4233         CloseHandle(handle);
4234     }
4235
4236     IStream_Release(stm);
4237     IStorage_Release(stg);
4238
4239     return TRUE;
4240 }
4241
4242 static void test_lastusedsource(void)
4243 {
4244     static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4245
4246     UINT r;
4247     char value[MAX_PATH], path[MAX_PATH];
4248     DWORD size;
4249
4250     if (!pMsiSourceListGetInfoA)
4251     {
4252         win_skip("MsiSourceListGetInfoA is not available\n");
4253         return;
4254     }
4255
4256     CreateDirectoryA("msitest", NULL);
4257     create_file("maximus", 500);
4258     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4259     DeleteFile("maximus");
4260
4261     create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
4262     create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
4263     create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
4264
4265     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4266
4267     /* no cabinet file */
4268
4269     size = MAX_PATH;
4270     lstrcpyA(value, "aaa");
4271     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4272                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4273     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4274     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4275
4276     r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
4277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4278
4279     lstrcpyA(path, CURR_DIR);
4280     lstrcatA(path, "\\");
4281
4282     size = MAX_PATH;
4283     lstrcpyA(value, "aaa");
4284     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4285                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4287     todo_wine
4288     {
4289     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4290     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4291     }
4292
4293     r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
4294     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4295
4296     /* separate cabinet file */
4297
4298     size = MAX_PATH;
4299     lstrcpyA(value, "aaa");
4300     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4301                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4302     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4303     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4304
4305     r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
4306     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4307
4308     lstrcpyA(path, CURR_DIR);
4309     lstrcatA(path, "\\");
4310
4311     size = MAX_PATH;
4312     lstrcpyA(value, "aaa");
4313     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4314                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4315     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4316     todo_wine
4317     {
4318     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4319     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4320     }
4321
4322     r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
4323     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4324
4325     size = MAX_PATH;
4326     lstrcpyA(value, "aaa");
4327     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4328                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4329     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4330     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4331
4332     /* embedded cabinet stream */
4333
4334     add_cabinet_storage("msifile2.msi", "test1.cab");
4335
4336     r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
4337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4338
4339     size = MAX_PATH;
4340     lstrcpyA(value, "aaa");
4341     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4342                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4344     todo_wine
4345     {
4346     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4347     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4348     }
4349
4350     r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
4351     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4352
4353     size = MAX_PATH;
4354     lstrcpyA(value, "aaa");
4355     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4356                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4357     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4358     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4359
4360     /* Delete the files in the temp (current) folder */
4361     delete_cab_files();
4362     DeleteFile("msitest\\maximus");
4363     RemoveDirectory("msitest");
4364     DeleteFile("msifile0.msi");
4365     DeleteFile("msifile1.msi");
4366     DeleteFile("msifile2.msi");
4367 }
4368
4369 static void test_setdirproperty(void)
4370 {
4371     UINT r;
4372
4373     CreateDirectoryA("msitest", NULL);
4374     create_file("msitest\\maximus", 500);
4375     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
4376
4377     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4378
4379     r = MsiInstallProductA(msifile, NULL);
4380     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4381     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
4382     ok(delete_cf("msitest", FALSE), "File not installed\n");
4383
4384     /* Delete the files in the temp (current) folder */
4385     DeleteFile(msifile);
4386     DeleteFile("msitest\\maximus");
4387     RemoveDirectory("msitest");
4388 }
4389
4390 static void test_cabisextracted(void)
4391 {
4392     UINT r;
4393
4394     CreateDirectoryA("msitest", NULL);
4395     create_file("msitest\\gaius", 500);
4396     create_file("maximus", 500);
4397     create_file("augustus", 500);
4398     create_file("caesar", 500);
4399
4400     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4401     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
4402     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
4403
4404     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
4405
4406     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4407
4408     r = MsiInstallProductA(msifile, NULL);
4409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4410     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4411     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4412     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4413     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
4414     ok(delete_pf("msitest", FALSE), "File not installed\n");
4415
4416     /* Delete the files in the temp (current) folder */
4417     delete_cab_files();
4418     DeleteFile(msifile);
4419     DeleteFile("maximus");
4420     DeleteFile("augustus");
4421     DeleteFile("caesar");
4422     DeleteFile("msitest\\gaius");
4423     RemoveDirectory("msitest");
4424 }
4425
4426 static void test_concurrentinstall(void)
4427 {
4428     UINT r;
4429     CHAR path[MAX_PATH];
4430
4431     CreateDirectoryA("msitest", NULL);
4432     CreateDirectoryA("msitest\\msitest", NULL);
4433     create_file("msitest\\maximus", 500);
4434     create_file("msitest\\msitest\\augustus", 500);
4435
4436     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
4437
4438     lstrcpyA(path, CURR_DIR);
4439     lstrcatA(path, "\\msitest\\concurrent.msi");
4440     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
4441
4442     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4443
4444     r = MsiInstallProductA(msifile, NULL);
4445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4446     if (!delete_pf("msitest\\augustus", TRUE))
4447         trace("concurrent installs not supported\n");
4448     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4449     ok(delete_pf("msitest", FALSE), "File not installed\n");
4450
4451     DeleteFile(path);
4452
4453     r = MsiInstallProductA(msifile, NULL);
4454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4455     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4456     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4457     ok(delete_pf("msitest", FALSE), "File not installed\n");
4458
4459     DeleteFile(msifile);
4460     DeleteFile("msitest\\msitest\\augustus");
4461     DeleteFile("msitest\\maximus");
4462     RemoveDirectory("msitest\\msitest");
4463     RemoveDirectory("msitest");
4464 }
4465
4466 static void test_setpropertyfolder(void)
4467 {
4468     UINT r;
4469     CHAR path[MAX_PATH];
4470     DWORD attr;
4471
4472     lstrcpyA(path, PROG_FILES_DIR);
4473     lstrcatA(path, "\\msitest\\added");
4474
4475     CreateDirectoryA("msitest", NULL);
4476     create_file("msitest\\maximus", 500);
4477
4478     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
4479
4480     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4481
4482     r = MsiInstallProductA(msifile, NULL);
4483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4484     attr = GetFileAttributesA(path);
4485     if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
4486     {
4487         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
4488         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
4489         ok(delete_pf("msitest", FALSE), "File not installed\n");
4490     }
4491     else
4492     {
4493         trace("changing folder property not supported\n");
4494         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4495         ok(delete_pf("msitest", FALSE), "File not installed\n");
4496     }
4497
4498     /* Delete the files in the temp (current) folder */
4499     DeleteFile(msifile);
4500     DeleteFile("msitest\\maximus");
4501     RemoveDirectory("msitest");
4502 }
4503
4504 static BOOL file_exists(LPCSTR file)
4505 {
4506     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
4507 }
4508
4509 static BOOL pf_exists(LPCSTR file)
4510 {
4511     CHAR path[MAX_PATH];
4512
4513     lstrcpyA(path, PROG_FILES_DIR);
4514     lstrcatA(path, "\\");
4515     lstrcatA(path, file);
4516
4517     return file_exists(path);
4518 }
4519
4520 static void delete_pfmsitest_files(void)
4521 {
4522     SHFILEOPSTRUCT shfl;
4523     CHAR path[MAX_PATH+11];
4524
4525     lstrcpyA(path, PROG_FILES_DIR);
4526     lstrcatA(path, "\\msitest\\*");
4527     path[strlen(path) + 1] = '\0';
4528
4529     shfl.hwnd = NULL;
4530     shfl.wFunc = FO_DELETE;
4531     shfl.pFrom = path;
4532     shfl.pTo = NULL;
4533     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
4534
4535     SHFileOperation(&shfl);
4536
4537     lstrcpyA(path, PROG_FILES_DIR);
4538     lstrcatA(path, "\\msitest");
4539     RemoveDirectoryA(path);
4540 }
4541
4542 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
4543 {
4544     char val[MAX_PATH];
4545     DWORD size, type;
4546     LONG res;
4547
4548     size = MAX_PATH;
4549     val[0] = '\0';
4550     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
4551
4552     if (res != ERROR_SUCCESS ||
4553         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
4554     {
4555         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4556         return;
4557     }
4558
4559     if (!expected)
4560         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
4561     else
4562     {
4563         if (bcase)
4564             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
4565         else
4566             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
4567     }
4568 }
4569
4570 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
4571 {
4572     DWORD val, size, type;
4573     LONG res;
4574
4575     size = sizeof(DWORD);
4576     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4577
4578     if (res != ERROR_SUCCESS || type != REG_DWORD)
4579     {
4580         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4581         return;
4582     }
4583
4584     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
4585 }
4586
4587 static void check_reg_dword2(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD line)
4588 {
4589     DWORD val, size, type;
4590     LONG res;
4591
4592     size = sizeof(DWORD);
4593     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4594
4595     if (res != ERROR_SUCCESS || type != REG_DWORD)
4596     {
4597         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4598         return;
4599     }
4600
4601     ok_(__FILE__, line)(val == expected1 || val == expected2, "Expected %d or %d, got %d\n", expected1, expected2, val);
4602 }
4603
4604 static void check_reg_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line)
4605 {
4606     DWORD val, size, type;
4607     LONG res;
4608
4609     size = sizeof(DWORD);
4610     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4611
4612     if (res != ERROR_SUCCESS || type != REG_DWORD)
4613     {
4614         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4615         return;
4616     }
4617
4618     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3,
4619                         "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val);
4620 }
4621
4622 #define CHECK_REG_STR(prodkey, name, expected) \
4623     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
4624
4625 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
4626     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
4627     RegDeleteValueA(prodkey, name);
4628
4629 #define CHECK_REG_ISTR(prodkey, name, expected) \
4630     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
4631
4632 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
4633     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
4634     RegDeleteValueA(prodkey, name);
4635
4636 #define CHECK_REG_DWORD(prodkey, name, expected) \
4637     check_reg_dword(prodkey, name, expected, __LINE__);
4638
4639 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
4640     check_reg_dword(prodkey, name, expected, __LINE__); \
4641     RegDeleteValueA(prodkey, name);
4642
4643 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
4644     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
4645
4646 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
4647     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
4648     RegDeleteValueA(prodkey, name);
4649
4650 #define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4651     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__);
4652
4653 #define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4654     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \
4655     RegDeleteValueA(prodkey, name);
4656
4657 static void get_date_str(LPSTR date)
4658 {
4659     SYSTEMTIME systime;
4660
4661     static const char date_fmt[] = "%d%02d%02d";
4662     GetLocalTime(&systime);
4663     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
4664 }
4665
4666 static void test_publish_registerproduct(void)
4667 {
4668     UINT r;
4669     LONG res;
4670     HKEY hkey;
4671     HKEY props, usage;
4672     LPSTR usersid;
4673     char date[MAX_PATH];
4674     char temp[MAX_PATH];
4675     char keypath[MAX_PATH];
4676
4677     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4678                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4679     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4680                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4681     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4682                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4683     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4684                                     "\\51AAE0C44620A5E4788506E91F249BD2";
4685
4686     if (!get_user_sid(&usersid))
4687         return;
4688
4689     get_date_str(date);
4690     GetTempPath(MAX_PATH, temp);
4691
4692     CreateDirectoryA("msitest", NULL);
4693     create_file("msitest\\maximus", 500);
4694
4695     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4696
4697     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4698
4699     /* RegisterProduct */
4700     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4702     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4703     ok(delete_pf("msitest", FALSE), "File not installed\n");
4704
4705     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
4706     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4707
4708     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4710
4711     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4712     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4713     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4714     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4715     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4716     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4717     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4718     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4719     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4720     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4721     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4722     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4723     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4724     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4725     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4726     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4727     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4728     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4729     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4730     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4731     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4732     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4733     todo_wine
4734     {
4735         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4736     }
4737
4738     RegDeleteKeyA(hkey, "");
4739     RegCloseKey(hkey);
4740
4741     sprintf(keypath, userdata, usersid);
4742     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4744
4745     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4747
4748     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4749     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4750     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4751     CHECK_DEL_REG_STR(props, "InstallDate", date);
4752     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4753     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4754     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4755     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4756     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4757     CHECK_DEL_REG_STR(props, "Comments", NULL);
4758     CHECK_DEL_REG_STR(props, "Contact", NULL);
4759     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4760     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4761     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4762     CHECK_DEL_REG_STR(props, "Readme", NULL);
4763     CHECK_DEL_REG_STR(props, "Size", NULL);
4764     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4765     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4766     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4767     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4768     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4769     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4770     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4771     todo_wine
4772     {
4773         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4774     }
4775
4776     RegDeleteKeyA(props, "");
4777     RegCloseKey(props);
4778
4779     res = RegOpenKeyA(hkey, "Usage", &usage);
4780     todo_wine
4781     {
4782         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4783     }
4784
4785     RegDeleteKeyA(usage, "");
4786     RegCloseKey(usage);
4787     RegDeleteKeyA(hkey, "");
4788     RegCloseKey(hkey);
4789
4790     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4792
4793     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4794
4795     RegDeleteKeyA(hkey, "");
4796     RegCloseKey(hkey);
4797
4798     /* RegisterProduct, machine */
4799     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
4800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4801     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4802     ok(delete_pf("msitest", FALSE), "File not installed\n");
4803
4804     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
4805     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4806
4807     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4808     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4809
4810     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4811     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4812     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4813     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4814     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4815     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4816     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4817     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4818     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4819     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4820     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4821     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4822     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4823     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4824     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4825     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4826     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4827     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4828     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4829     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4830     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4831     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4832     todo_wine
4833     {
4834         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4835     }
4836
4837     RegDeleteKeyA(hkey, "");
4838     RegCloseKey(hkey);
4839
4840     sprintf(keypath, userdata, "S-1-5-18");
4841     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4842     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4843
4844     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4845     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4846
4847     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4848     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4849     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4850     CHECK_DEL_REG_STR(props, "InstallDate", date);
4851     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4852     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4853     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4854     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4855     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4856     CHECK_DEL_REG_STR(props, "Comments", NULL);
4857     CHECK_DEL_REG_STR(props, "Contact", NULL);
4858     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4859     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4860     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4861     CHECK_DEL_REG_STR(props, "Readme", NULL);
4862     CHECK_DEL_REG_STR(props, "Size", NULL);
4863     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4864     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4865     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4866     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4867     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4868     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4869     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4870     todo_wine
4871     {
4872         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4873     }
4874
4875     RegDeleteKeyA(props, "");
4876     RegCloseKey(props);
4877
4878     res = RegOpenKeyA(hkey, "Usage", &usage);
4879     todo_wine
4880     {
4881         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4882     }
4883
4884     RegDeleteKeyA(usage, "");
4885     RegCloseKey(usage);
4886     RegDeleteKeyA(hkey, "");
4887     RegCloseKey(hkey);
4888
4889     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4891
4892     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4893
4894     RegDeleteKeyA(hkey, "");
4895     RegCloseKey(hkey);
4896
4897     DeleteFile(msifile);
4898     DeleteFile("msitest\\maximus");
4899     RemoveDirectory("msitest");
4900     HeapFree(GetProcessHeap(), 0, usersid);
4901 }
4902
4903 static void test_publish_publishproduct(void)
4904 {
4905     UINT r;
4906     LONG res;
4907     LPSTR usersid;
4908     HKEY sourcelist, net, props;
4909     HKEY hkey, patches, media;
4910     CHAR keypath[MAX_PATH];
4911     CHAR temp[MAX_PATH];
4912     CHAR path[MAX_PATH];
4913     BOOL old_installer = FALSE;
4914
4915     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4916                                    "\\Installer\\UserData\\%s\\Products"
4917                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4918     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
4919                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4920     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4921                                      "\\51AAE0C44620A5E4788506E91F249BD2";
4922     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4923                                   "\\Installer\\Products"
4924                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4925     static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4926     static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4927
4928     if (!get_user_sid(&usersid))
4929         return;
4930
4931     GetTempPath(MAX_PATH, temp);
4932
4933     CreateDirectoryA("msitest", NULL);
4934     create_file("msitest\\maximus", 500);
4935
4936     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4937
4938     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4939
4940     /* PublishProduct, current user */
4941     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4942     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4943     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4944     ok(delete_pf("msitest", FALSE), "File not installed\n");
4945
4946     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4947     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4948
4949     sprintf(keypath, prodpath, usersid);
4950     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4951     if (res == ERROR_FILE_NOT_FOUND)
4952     {
4953         res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4954         if (res == ERROR_SUCCESS)
4955         {
4956             win_skip("Windows Installer < 3.0 detected\n");
4957             RegCloseKey(hkey);
4958             old_installer = TRUE;
4959             goto currentuser;
4960         }
4961         else
4962         {
4963             win_skip("Install failed, no need to continue\n");
4964             return;
4965         }
4966     }
4967     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4968
4969     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4970     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4971
4972     res = RegOpenKeyA(hkey, "Patches", &patches);
4973     todo_wine
4974     {
4975         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4976
4977         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4978     }
4979
4980     RegDeleteKeyA(patches, "");
4981     RegCloseKey(patches);
4982     RegDeleteKeyA(hkey, "");
4983     RegCloseKey(hkey);
4984
4985 currentuser:
4986     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4987     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4988
4989     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4990     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4991     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4992     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4993     if (!old_installer)
4994         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4995     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
4996     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4997     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4998     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4999
5000     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
5001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5002
5003     lstrcpyA(path, "n;1;");
5004     lstrcatA(path, temp);
5005     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
5006     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
5007
5008     res = RegOpenKeyA(sourcelist, "Net", &net);
5009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5010
5011     CHECK_DEL_REG_STR(net, "1", temp);
5012
5013     RegDeleteKeyA(net, "");
5014     RegCloseKey(net);
5015
5016     res = RegOpenKeyA(sourcelist, "Media", &media);
5017     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5018
5019     CHECK_DEL_REG_STR(media, "1", "DISK1;");
5020
5021     RegDeleteKeyA(media, "");
5022     RegCloseKey(media);
5023     RegDeleteKeyA(sourcelist, "");
5024     RegCloseKey(sourcelist);
5025     RegDeleteKeyA(hkey, "");
5026     RegCloseKey(hkey);
5027
5028     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
5029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5030
5031     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
5032
5033     RegDeleteKeyA(hkey, "");
5034     RegCloseKey(hkey);
5035
5036     /* PublishProduct, machine */
5037     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
5038     if (old_installer)
5039         goto machprod;
5040     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5041     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5042     ok(delete_pf("msitest", FALSE), "File not installed\n");
5043
5044     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
5045     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5046
5047     sprintf(keypath, prodpath, "S-1-5-18");
5048     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
5049     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5050
5051     res = RegOpenKeyA(hkey, "InstallProperties", &props);
5052     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5053
5054     res = RegOpenKeyA(hkey, "Patches", &patches);
5055     todo_wine
5056     {
5057         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5058
5059         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
5060     }
5061
5062     RegDeleteKeyA(patches, "");
5063     RegCloseKey(patches);
5064     RegDeleteKeyA(hkey, "");
5065     RegCloseKey(hkey);
5066
5067 machprod:
5068     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
5069     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5070
5071     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
5072     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
5073     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
5074     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
5075     if (!old_installer)
5076         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
5077     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
5078     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
5079     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
5080     CHECK_DEL_REG_STR(hkey, "Clients", ":");
5081
5082     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
5083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5084
5085     lstrcpyA(path, "n;1;");
5086     lstrcatA(path, temp);
5087     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
5088     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
5089
5090     res = RegOpenKeyA(sourcelist, "Net", &net);
5091     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5092
5093     CHECK_DEL_REG_STR(net, "1", temp);
5094
5095     RegDeleteKeyA(net, "");
5096     RegCloseKey(net);
5097
5098     res = RegOpenKeyA(sourcelist, "Media", &media);
5099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5100
5101     CHECK_DEL_REG_STR(media, "1", "DISK1;");
5102
5103     RegDeleteKeyA(media, "");
5104     RegCloseKey(media);
5105     RegDeleteKeyA(sourcelist, "");
5106     RegCloseKey(sourcelist);
5107     RegDeleteKeyA(hkey, "");
5108     RegCloseKey(hkey);
5109
5110     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
5111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5112
5113     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
5114
5115     RegDeleteKeyA(hkey, "");
5116     RegCloseKey(hkey);
5117
5118     DeleteFile(msifile);
5119     DeleteFile("msitest\\maximus");
5120     RemoveDirectory("msitest");
5121     HeapFree(GetProcessHeap(), 0, usersid);
5122 }
5123
5124 static void test_publish_publishfeatures(void)
5125 {
5126     UINT r;
5127     LONG res;
5128     HKEY hkey;
5129     LPSTR usersid;
5130     CHAR keypath[MAX_PATH];
5131
5132     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
5133                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
5134     static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
5135                                  "\\Installer\\UserData\\%s\\Products"
5136                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
5137     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
5138                                   "\\Installer\\Features";
5139     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
5140                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
5141
5142     if (!get_user_sid(&usersid))
5143         return;
5144
5145     CreateDirectoryA("msitest", NULL);
5146     create_file("msitest\\maximus", 500);
5147
5148     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5149
5150     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5151
5152     /* PublishFeatures, current user */
5153     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
5154     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5155     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5156     ok(delete_pf("msitest", FALSE), "File not installed\n");
5157
5158     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
5159     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5160
5161     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
5162     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5163
5164     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
5165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5166
5167     CHECK_REG_STR(hkey, "feature", "");
5168     CHECK_REG_STR(hkey, "montecristo", "");
5169
5170     RegDeleteValueA(hkey, "feature");
5171     RegDeleteValueA(hkey, "montecristo");
5172     RegDeleteKeyA(hkey, "");
5173     RegCloseKey(hkey);
5174
5175     sprintf(keypath, udpath, usersid);
5176     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
5177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5178
5179     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
5180     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
5181
5182     RegDeleteValueA(hkey, "feature");
5183     RegDeleteValueA(hkey, "montecristo");
5184     RegDeleteKeyA(hkey, "");
5185     RegCloseKey(hkey);
5186
5187     /* PublishFeatures, machine */
5188     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
5189     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5190     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5191     ok(delete_pf("msitest", FALSE), "File not installed\n");
5192
5193     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
5194     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5195
5196     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
5197     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5198
5199     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
5200     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5201
5202     CHECK_REG_STR(hkey, "feature", "");
5203     CHECK_REG_STR(hkey, "montecristo", "");
5204
5205     RegDeleteValueA(hkey, "feature");
5206     RegDeleteValueA(hkey, "montecristo");
5207     RegDeleteKeyA(hkey, "");
5208     RegCloseKey(hkey);
5209
5210     sprintf(keypath, udpath, "S-1-5-18");
5211     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
5212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5213
5214     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
5215     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
5216
5217     RegDeleteValueA(hkey, "feature");
5218     RegDeleteValueA(hkey, "montecristo");
5219     RegDeleteKeyA(hkey, "");
5220     RegCloseKey(hkey);
5221
5222     DeleteFile(msifile);
5223     DeleteFile("msitest\\maximus");
5224     RemoveDirectory("msitest");
5225     HeapFree(GetProcessHeap(), 0, usersid);
5226 }
5227
5228 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
5229 {
5230     DWORD len = 0;
5231     LPSTR val;
5232     LONG r;
5233
5234     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
5235     if (r != ERROR_SUCCESS)
5236         return NULL;
5237
5238     len += sizeof (WCHAR);
5239     val = HeapAlloc(GetProcessHeap(), 0, len);
5240     if (!val) return NULL;
5241     val[0] = 0;
5242     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
5243     return val;
5244 }
5245
5246 static void get_owner_company(LPSTR *owner, LPSTR *company)
5247 {
5248     LONG res;
5249     HKEY hkey;
5250
5251     *owner = *company = NULL;
5252
5253     res = RegOpenKeyA(HKEY_CURRENT_USER,
5254                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
5255     if (res == ERROR_SUCCESS)
5256     {
5257         *owner = reg_get_val_str(hkey, "DefName");
5258         *company = reg_get_val_str(hkey, "DefCompany");
5259         RegCloseKey(hkey);
5260     }
5261
5262     if (!*owner || !*company)
5263     {
5264         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
5265                           "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
5266         if (res == ERROR_SUCCESS)
5267         {
5268             *owner = reg_get_val_str(hkey, "RegisteredOwner");
5269             *company = reg_get_val_str(hkey, "RegisteredOrganization");
5270             RegCloseKey(hkey);
5271         }
5272     }
5273
5274     if (!*owner || !*company)
5275     {
5276         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
5277                           "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
5278         if (res == ERROR_SUCCESS)
5279         {
5280             *owner = reg_get_val_str(hkey, "RegisteredOwner");
5281             *company = reg_get_val_str(hkey, "RegisteredOrganization");
5282             RegCloseKey(hkey);
5283         }
5284     }
5285 }
5286
5287 static void test_publish_registeruser(void)
5288 {
5289     UINT r;
5290     LONG res;
5291     HKEY props;
5292     LPSTR usersid;
5293     LPSTR owner, company;
5294     CHAR keypath[MAX_PATH];
5295
5296     static const CHAR keyfmt[] =
5297         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
5298         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
5299
5300     if (!get_user_sid(&usersid))
5301         return;
5302
5303     get_owner_company(&owner, &company);
5304
5305     CreateDirectoryA("msitest", NULL);
5306     create_file("msitest\\maximus", 500);
5307
5308     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5309
5310     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5311
5312     /* RegisterUser, per-user */
5313     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
5314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5315     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5316     ok(delete_pf("msitest", FALSE), "File not installed\n");
5317
5318     sprintf(keypath, keyfmt, usersid);
5319
5320     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5322
5323     CHECK_REG_STR(props, "ProductID", "none");
5324     CHECK_REG_STR(props, "RegCompany", company);
5325     CHECK_REG_STR(props, "RegOwner", owner);
5326
5327     RegDeleteValueA(props, "ProductID");
5328     RegDeleteValueA(props, "RegCompany");
5329     RegDeleteValueA(props, "RegOwner");
5330     RegDeleteKeyA(props, "");
5331     RegCloseKey(props);
5332
5333     /* RegisterUser, machine */
5334     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
5335     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5336     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5337     ok(delete_pf("msitest", FALSE), "File not installed\n");
5338
5339     sprintf(keypath, keyfmt, "S-1-5-18");
5340
5341     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5343
5344     CHECK_REG_STR(props, "ProductID", "none");
5345     CHECK_REG_STR(props, "RegCompany", company);
5346     CHECK_REG_STR(props, "RegOwner", owner);
5347
5348     RegDeleteValueA(props, "ProductID");
5349     RegDeleteValueA(props, "RegCompany");
5350     RegDeleteValueA(props, "RegOwner");
5351     RegDeleteKeyA(props, "");
5352     RegCloseKey(props);
5353
5354     HeapFree(GetProcessHeap(), 0, company);
5355     HeapFree(GetProcessHeap(), 0, owner);
5356
5357     DeleteFile(msifile);
5358     DeleteFile("msitest\\maximus");
5359     RemoveDirectory("msitest");
5360     LocalFree(usersid);
5361 }
5362
5363 static void test_publish_processcomponents(void)
5364 {
5365     UINT r;
5366     LONG res;
5367     DWORD size;
5368     HKEY comp, hkey;
5369     LPSTR usersid;
5370     CHAR val[MAX_PATH];
5371     CHAR keypath[MAX_PATH];
5372     CHAR program_files_maximus[MAX_PATH];
5373
5374     static const CHAR keyfmt[] =
5375         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
5376         "UserData\\%s\\Components\\%s";
5377     static const CHAR compkey[] =
5378         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
5379
5380     if (!get_user_sid(&usersid))
5381         return;
5382
5383     CreateDirectoryA("msitest", NULL);
5384     create_file("msitest\\maximus", 500);
5385
5386     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
5387
5388     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5389
5390     /* ProcessComponents, per-user */
5391     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5392     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5393     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5394     ok(delete_pf("msitest", FALSE), "File not installed\n");
5395
5396     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
5397
5398     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5400
5401     size = MAX_PATH;
5402     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5403                            NULL, NULL, (LPBYTE)val, &size);
5404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5405
5406     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
5407     lstrcatA(program_files_maximus,"\\msitest\\maximus");
5408
5409     ok(!lstrcmpiA(val, program_files_maximus),
5410        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5411
5412     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5413     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5414
5415     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5416     RegDeleteKeyA(comp, "");
5417     RegCloseKey(comp);
5418
5419     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
5420
5421     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5423
5424     size = MAX_PATH;
5425     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5426                            NULL, NULL, (LPBYTE)val, &size);
5427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5428     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5429        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5430
5431     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5432     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5433
5434     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5435     RegDeleteKeyA(comp, "");
5436     RegCloseKey(comp);
5437
5438     /* ProcessComponents, machine */
5439     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
5440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5441     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5442     ok(delete_pf("msitest", FALSE), "File not installed\n");
5443
5444     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
5445
5446     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5447     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5448
5449     size = MAX_PATH;
5450     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5451                            NULL, NULL, (LPBYTE)val, &size);
5452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5453     ok(!lstrcmpiA(val, program_files_maximus),
5454        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5455
5456     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5457     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5458
5459     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5460     RegDeleteKeyA(comp, "");
5461     RegCloseKey(comp);
5462
5463     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
5464
5465     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5467
5468     size = MAX_PATH;
5469     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5470                            NULL, NULL, (LPBYTE)val, &size);
5471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5472     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5473        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5474
5475     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5476     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5477
5478     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5479     RegDeleteKeyA(comp, "");
5480     RegCloseKey(comp);
5481
5482     DeleteFile(msifile);
5483     DeleteFile("msitest\\maximus");
5484     RemoveDirectory("msitest");
5485     LocalFree(usersid);
5486 }
5487
5488 static void test_publish(void)
5489 {
5490     UINT r;
5491     LONG res;
5492     HKEY uninstall, prodkey;
5493     INSTALLSTATE state;
5494     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5495     char date[MAX_PATH];
5496     char temp[MAX_PATH];
5497
5498     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
5499
5500     if (!pMsiQueryComponentStateA)
5501     {
5502         win_skip("MsiQueryComponentStateA is not available\n");
5503         return;
5504     }
5505
5506     get_date_str(date);
5507     GetTempPath(MAX_PATH, temp);
5508
5509     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
5510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5511
5512     CreateDirectoryA("msitest", NULL);
5513     create_file("msitest\\maximus", 500);
5514
5515     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5516
5517     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5518
5519     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5520     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5521
5522     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5523     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5524
5525     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5526     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5527
5528     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5529                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5530     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5531     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5532
5533     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5534     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5535
5536     /* nothing published */
5537     r = MsiInstallProductA(msifile, NULL);
5538     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5539     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5540     ok(pf_exists("msitest"), "File not installed\n");
5541
5542     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5543     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5544
5545     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5546     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5547
5548     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5549     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5550
5551     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5552                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5553     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5554     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5555
5556     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5557     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5558
5559     /* PublishProduct and RegisterProduct */
5560     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
5561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5562     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5563     ok(pf_exists("msitest"), "File not installed\n");
5564
5565     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5566     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5567
5568     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5569     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5570
5571     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5572     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5573
5574     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5575                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5576     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
5577     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5578
5579     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5580     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5581
5582     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5583     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5584     CHECK_REG_STR(prodkey, "InstallDate", date);
5585     CHECK_REG_STR(prodkey, "InstallSource", temp);
5586     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5587     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5588     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5589     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5590     CHECK_REG_STR(prodkey, "Comments", NULL);
5591     CHECK_REG_STR(prodkey, "Contact", NULL);
5592     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5593     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5594     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5595     CHECK_REG_STR(prodkey, "Readme", NULL);
5596     CHECK_REG_STR(prodkey, "Size", NULL);
5597     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5598     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5599     CHECK_REG_DWORD(prodkey, "Language", 1033);
5600     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5601     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5602     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5603     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5604     todo_wine
5605     {
5606         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5607     }
5608
5609     RegCloseKey(prodkey);
5610
5611     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5612     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5613     ok(pf_exists("msitest\\maximus"), "File deleted\n");
5614     ok(pf_exists("msitest"), "File deleted\n");
5615
5616     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5617     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5618
5619     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5620     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5621
5622     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5623     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5624
5625     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5626                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5627     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5628     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5629
5630     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5631     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5632
5633     /* complete install */
5634     r = MsiInstallProductA(msifile, "FULL=1");
5635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5636     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5637     ok(pf_exists("msitest"), "File not installed\n");
5638
5639     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5640     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5641
5642     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5643     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5644
5645     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5646     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5647
5648     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5649                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5650     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5651     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5652
5653     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5655
5656     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5657     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5658     CHECK_REG_STR(prodkey, "InstallDate", date);
5659     CHECK_REG_STR(prodkey, "InstallSource", temp);
5660     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5661     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5662     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5663     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5664     CHECK_REG_STR(prodkey, "Comments", NULL);
5665     CHECK_REG_STR(prodkey, "Contact", NULL);
5666     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5667     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5668     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5669     CHECK_REG_STR(prodkey, "Readme", NULL);
5670     CHECK_REG_STR(prodkey, "Size", NULL);
5671     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5672     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5673     CHECK_REG_DWORD(prodkey, "Language", 1033);
5674     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5675     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5676     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5677     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5678     todo_wine
5679     {
5680         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5681     }
5682
5683     RegCloseKey(prodkey);
5684
5685     /* no UnpublishFeatures */
5686     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5687     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5688     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5689     ok(!pf_exists("msitest"), "Directory not deleted\n");
5690
5691     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5692     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5693
5694     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5695     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5696
5697     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5698     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5699
5700     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5701                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5702     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5703     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5704
5705     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5706     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5707
5708     /* complete install */
5709     r = MsiInstallProductA(msifile, "FULL=1");
5710     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5711     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5712     ok(pf_exists("msitest"), "File not installed\n");
5713
5714     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5715     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5716
5717     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5718     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5719
5720     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5721     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5722
5723     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5724                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5726     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5727
5728     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5730
5731     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5732     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5733     CHECK_REG_STR(prodkey, "InstallDate", date);
5734     CHECK_REG_STR(prodkey, "InstallSource", temp);
5735     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5736     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5737     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5738     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5739     CHECK_REG_STR(prodkey, "Comments", NULL);
5740     CHECK_REG_STR(prodkey, "Contact", NULL);
5741     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5742     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5743     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5744     CHECK_REG_STR(prodkey, "Readme", NULL);
5745     CHECK_REG_STR(prodkey, "Size", NULL);
5746     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5747     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5748     CHECK_REG_DWORD(prodkey, "Language", 1033);
5749     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5750     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5751     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5752     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5753     todo_wine
5754     {
5755         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5756     }
5757
5758     RegCloseKey(prodkey);
5759
5760     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
5761     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
5762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5763     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
5764     todo_wine ok(pf_exists("msitest"), "Directory deleted\n");
5765
5766     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5767     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5768
5769     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5770     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5771
5772     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5773     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5774
5775     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5776                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5778     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5779
5780     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5782
5783     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5784     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5785     CHECK_REG_STR(prodkey, "InstallDate", date);
5786     CHECK_REG_STR(prodkey, "InstallSource", temp);
5787     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5788     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5789     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5790     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5791     CHECK_REG_STR(prodkey, "Comments", NULL);
5792     CHECK_REG_STR(prodkey, "Contact", NULL);
5793     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5794     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5795     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5796     CHECK_REG_STR(prodkey, "Readme", NULL);
5797     CHECK_REG_STR(prodkey, "Size", NULL);
5798     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5799     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5800     CHECK_REG_DWORD(prodkey, "Language", 1033);
5801     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5802     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5803     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5804     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5805     todo_wine
5806     {
5807         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5808     }
5809
5810     RegCloseKey(prodkey);
5811
5812     /* complete install */
5813     r = MsiInstallProductA(msifile, "FULL=1");
5814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5815     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5816     ok(pf_exists("msitest"), "File not installed\n");
5817
5818     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5819     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5820
5821     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5822     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5823
5824     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5825     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5826
5827     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5828                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5829     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5830     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5831
5832     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5833     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5834
5835     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5836     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5837     CHECK_REG_STR(prodkey, "InstallDate", date);
5838     CHECK_REG_STR(prodkey, "InstallSource", temp);
5839     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5840     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5841     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5842     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5843     CHECK_REG_STR(prodkey, "Comments", NULL);
5844     CHECK_REG_STR(prodkey, "Contact", NULL);
5845     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5846     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5847     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5848     CHECK_REG_STR(prodkey, "Readme", NULL);
5849     CHECK_REG_STR(prodkey, "Size", NULL);
5850     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5851     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5852     CHECK_REG_DWORD(prodkey, "Language", 1033);
5853     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5854     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5855     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5856     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5857     todo_wine
5858     {
5859         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
5860     }
5861
5862     RegCloseKey(prodkey);
5863
5864     /* UnpublishFeatures, both features removed */
5865     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
5866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5867     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5868     ok(!pf_exists("msitest"), "Directory not deleted\n");
5869
5870     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5871     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5872
5873     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5874     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5875
5876     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5877     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5878
5879     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5880                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5881     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5882     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5883
5884     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5885     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5886
5887     /* complete install */
5888     r = MsiInstallProductA(msifile, "FULL=1");
5889     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5890     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5891     ok(pf_exists("msitest"), "File not installed\n");
5892
5893     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5894     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5895
5896     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5897     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5898
5899     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5900     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5901
5902     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5903                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5904     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5905     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5906
5907     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5909
5910     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5911     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5912     CHECK_REG_STR(prodkey, "InstallDate", date);
5913     CHECK_REG_STR(prodkey, "InstallSource", temp);
5914     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5915     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5916     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5917     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5918     CHECK_REG_STR(prodkey, "Comments", NULL);
5919     CHECK_REG_STR(prodkey, "Contact", NULL);
5920     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5921     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5922     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5923     CHECK_REG_STR(prodkey, "Readme", NULL);
5924     CHECK_REG_STR(prodkey, "Size", NULL);
5925     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5926     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5927     CHECK_REG_DWORD(prodkey, "Language", 1033);
5928     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5929     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5930     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5931     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5932     todo_wine
5933     {
5934         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5935     }
5936
5937     RegCloseKey(prodkey);
5938
5939     /* complete uninstall */
5940     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5942     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5943     ok(!pf_exists("msitest"), "Directory not deleted\n");
5944
5945     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5946     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5947
5948     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5949     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5950
5951     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5952     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5953
5954     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5955                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5956     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5957     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5958
5959     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5960     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5961
5962     /* make sure 'Program Files\msitest' is removed */
5963     delete_pfmsitest_files();
5964
5965     RegCloseKey(uninstall);
5966     DeleteFile(msifile);
5967     DeleteFile("msitest\\maximus");
5968     RemoveDirectory("msitest");
5969 }
5970
5971 static void test_publishsourcelist(void)
5972 {
5973     UINT r;
5974     DWORD size;
5975     CHAR value[MAX_PATH];
5976     CHAR path[MAX_PATH];
5977     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5978
5979     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
5980     {
5981         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
5982         return;
5983     }
5984
5985     CreateDirectoryA("msitest", NULL);
5986     create_file("msitest\\maximus", 500);
5987
5988     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5989
5990     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5991
5992     r = MsiInstallProductA(msifile, NULL);
5993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5994     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5995     ok(pf_exists("msitest"), "File not installed\n");
5996
5997     /* nothing published */
5998     size = MAX_PATH;
5999     lstrcpyA(value, "aaa");
6000     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6001                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6002     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6003     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6004     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6005
6006     size = MAX_PATH;
6007     lstrcpyA(value, "aaa");
6008     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6009                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6010     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6011     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6012     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6013
6014     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
6015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6016     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6017     ok(pf_exists("msitest"), "File not installed\n");
6018
6019     /* after RegisterProduct */
6020     size = MAX_PATH;
6021     lstrcpyA(value, "aaa");
6022     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6023                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6024     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6025     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6026     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6027
6028     size = MAX_PATH;
6029     lstrcpyA(value, "aaa");
6030     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6031                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6032     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6033     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6034     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6035
6036     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
6037     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6038     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6039     ok(pf_exists("msitest"), "File not installed\n");
6040
6041     /* after ProcessComponents */
6042     size = MAX_PATH;
6043     lstrcpyA(value, "aaa");
6044     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6045                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6046     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6047     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6048     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6049
6050     size = MAX_PATH;
6051     lstrcpyA(value, "aaa");
6052     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6053                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6054     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6055     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6056     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6057
6058     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
6059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6060     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6061     ok(pf_exists("msitest"), "File not installed\n");
6062
6063     /* after PublishFeatures */
6064     size = MAX_PATH;
6065     lstrcpyA(value, "aaa");
6066     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6067                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6068     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6069     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6070     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6071
6072     size = MAX_PATH;
6073     lstrcpyA(value, "aaa");
6074     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6075                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6076     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6077     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6078     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6079
6080     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
6081     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6082     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6083     ok(pf_exists("msitest"), "File not installed\n");
6084
6085     /* after PublishProduct */
6086     size = MAX_PATH;
6087     lstrcpyA(value, "aaa");
6088     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6089                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6091     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
6092     ok(size == 11, "Expected 11, got %d\n", size);
6093
6094     size = MAX_PATH;
6095     lstrcpyA(value, "aaa");
6096     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6097                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
6098     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6099     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
6100     ok(size == 0, "Expected 0, got %d\n", size);
6101
6102     size = MAX_PATH;
6103     lstrcpyA(value, "aaa");
6104     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6105                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
6106     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6107     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
6108     ok(size == 0, "Expected 0, got %d\n", size);
6109
6110     lstrcpyA(path, CURR_DIR);
6111     lstrcatA(path, "\\");
6112
6113     size = MAX_PATH;
6114     lstrcpyA(value, "aaa");
6115     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6116                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
6117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6118     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
6119     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
6120
6121     size = MAX_PATH;
6122     lstrcpyA(value, "aaa");
6123     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6124                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
6125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6126     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
6127     ok(size == 1, "Expected 1, got %d\n", size);
6128
6129     size = MAX_PATH;
6130     lstrcpyA(value, "aaa");
6131     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6132                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6133     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6134     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
6135     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
6136
6137     size = MAX_PATH;
6138     lstrcpyA(value, "aaa");
6139     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6140                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
6141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6142     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
6143     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
6144
6145     size = MAX_PATH;
6146     lstrcpyA(value, "aaa");
6147     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6148                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
6149     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6150     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
6151     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
6152
6153     /* complete uninstall */
6154     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
6155     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6156     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
6157     ok(!pf_exists("msitest"), "Directory not deleted\n");
6158
6159     /* make sure 'Program Files\msitest' is removed */
6160     delete_pfmsitest_files();
6161
6162     DeleteFile(msifile);
6163     DeleteFile("msitest\\maximus");
6164     RemoveDirectory("msitest");
6165 }
6166
6167 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
6168 {
6169     MSIHANDLE hview = 0;
6170     UINT r;
6171
6172     r = MsiDatabaseOpenView(hdb, query, &hview);
6173     if(r != ERROR_SUCCESS)
6174         return r;
6175
6176     r = MsiViewExecute(hview, hrec);
6177     if(r == ERROR_SUCCESS)
6178         r = MsiViewClose(hview);
6179     MsiCloseHandle(hview);
6180     return r;
6181 }
6182
6183 static void set_transform_summary_info(void)
6184 {
6185     UINT r;
6186     MSIHANDLE suminfo = 0;
6187
6188     /* build summary info */
6189     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
6190     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
6191
6192     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
6193     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
6194
6195     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
6196                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
6197                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
6198                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
6199     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
6200
6201     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
6202     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
6203
6204     r = MsiSummaryInfoPersist(suminfo);
6205     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
6206
6207     r = MsiCloseHandle(suminfo);
6208     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
6209 }
6210
6211 static void generate_transform(void)
6212 {
6213     MSIHANDLE hdb1, hdb2;
6214     LPCSTR query;
6215     UINT r;
6216
6217     /* start with two identical databases */
6218     CopyFile(msifile, msifile2, FALSE);
6219
6220     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
6221     ok(r == ERROR_SUCCESS , "Failed to create database\n");
6222
6223     r = MsiDatabaseCommit(hdb1);
6224     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6225
6226     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
6227     ok(r == ERROR_SUCCESS , "Failed to create database\n");
6228
6229     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
6230     r = run_query(hdb1, 0, query);
6231     ok(r == ERROR_SUCCESS, "failed to add property\n");
6232
6233     /* database needs to be committed */
6234     MsiDatabaseCommit(hdb1);
6235
6236     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
6237     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
6238
6239 #if 0  /* not implemented in wine yet */
6240     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
6241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6242 #endif
6243
6244     MsiCloseHandle(hdb1);
6245     MsiCloseHandle(hdb2);
6246 }
6247
6248 /* data for generating a transform */
6249
6250 /* tables transform names - encoded as they would be in an msi database file */
6251 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
6252 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
6253 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
6254
6255 /* data in each table */
6256 static const char data1[] = /* _StringData */
6257     "propval";  /* all the strings squashed together */
6258
6259 static const WCHAR data2[] = { /* _StringPool */
6260 /*  len, refs */
6261     0,   0,    /* string 0 ''     */
6262     4,   1,    /* string 1 'prop' */
6263     3,   1,    /* string 2 'val'  */
6264 };
6265
6266 static const WCHAR data3[] = { /* Property */
6267     0x0201, 0x0001, 0x0002,
6268 };
6269
6270 static const struct {
6271     LPCWSTR name;
6272     const void *data;
6273     DWORD size;
6274 } table_transform_data[] =
6275 {
6276     { name1, data1, sizeof data1 - 1 },
6277     { name2, data2, sizeof data2 },
6278     { name3, data3, sizeof data3 },
6279 };
6280
6281 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
6282
6283 static void generate_transform_manual(void)
6284 {
6285     IStorage *stg = NULL;
6286     IStream *stm;
6287     WCHAR name[0x20];
6288     HRESULT r;
6289     DWORD i, count;
6290     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
6291
6292     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
6293
6294     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
6295
6296     r = StgCreateDocfile(name, mode, 0, &stg);
6297     ok(r == S_OK, "failed to create storage\n");
6298     if (!stg)
6299         return;
6300
6301     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
6302     ok(r == S_OK, "failed to set storage type\n");
6303
6304     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
6305     {
6306         r = IStorage_CreateStream(stg, table_transform_data[i].name,
6307                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
6308         if (FAILED(r))
6309         {
6310             ok(0, "failed to create stream %08x\n", r);
6311             continue;
6312         }
6313
6314         r = IStream_Write(stm, table_transform_data[i].data,
6315                           table_transform_data[i].size, &count);
6316         if (FAILED(r) || count != table_transform_data[i].size)
6317             ok(0, "failed to write stream\n");
6318         IStream_Release(stm);
6319     }
6320
6321     IStorage_Release(stg);
6322
6323     set_transform_summary_info();
6324 }
6325
6326 static void test_transformprop(void)
6327 {
6328     UINT r;
6329
6330     CreateDirectoryA("msitest", NULL);
6331     create_file("msitest\\augustus", 500);
6332
6333     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
6334
6335     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6336
6337     r = MsiInstallProductA(msifile, NULL);
6338     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6339     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6340     ok(!delete_pf("msitest", FALSE), "File installed\n");
6341
6342     if (0)
6343         generate_transform();
6344     else
6345         generate_transform_manual();
6346
6347     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
6348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6349     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6350     ok(delete_pf("msitest", FALSE), "File not installed\n");
6351
6352     /* Delete the files in the temp (current) folder */
6353     DeleteFile(msifile);
6354     DeleteFile(msifile2);
6355     DeleteFile(mstfile);
6356     DeleteFile("msitest\\augustus");
6357     RemoveDirectory("msitest");
6358 }
6359
6360 static void test_currentworkingdir(void)
6361 {
6362     UINT r;
6363     CHAR drive[MAX_PATH], path[MAX_PATH];
6364     LPSTR ptr;
6365
6366     CreateDirectoryA("msitest", NULL);
6367     create_file("msitest\\augustus", 500);
6368
6369     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
6370
6371     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6372
6373     CreateDirectoryA("diffdir", NULL);
6374     SetCurrentDirectoryA("diffdir");
6375
6376     sprintf(path, "..\\%s", msifile);
6377     r = MsiInstallProductA(path, NULL);
6378     todo_wine
6379     {
6380         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
6381         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6382         ok(!delete_pf("msitest", FALSE), "File installed\n");
6383     }
6384
6385     sprintf(path, "%s\\%s", CURR_DIR, msifile);
6386     r = MsiInstallProductA(path, NULL);
6387     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6388     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6389     ok(delete_pf("msitest", FALSE), "File not installed\n");
6390
6391     lstrcpyA(drive, CURR_DIR);
6392     drive[2] = '\\';
6393     drive[3] = '\0';
6394     SetCurrentDirectoryA(drive);
6395
6396     lstrcpy(path, CURR_DIR);
6397     if (path[lstrlenA(path) - 1] != '\\')
6398         lstrcatA(path, "\\");
6399     lstrcatA(path, msifile);
6400     ptr = strchr(path, ':');
6401     ptr +=2;
6402
6403     r = MsiInstallProductA(ptr, NULL);
6404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6405     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6406     ok(delete_pf("msitest", FALSE), "File not installed\n");
6407
6408     SetCurrentDirectoryA(CURR_DIR);
6409
6410     DeleteFile(msifile);
6411     DeleteFile("msitest\\augustus");
6412     RemoveDirectory("msitest");
6413     RemoveDirectory("diffdir");
6414 }
6415
6416 static void set_admin_summary_info(const CHAR *name)
6417 {
6418     MSIHANDLE db, summary;
6419     UINT r;
6420
6421     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
6422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6423
6424     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6425     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6426
6427     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
6428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6429
6430     /* write the summary changes back to the stream */
6431     r = MsiSummaryInfoPersist(summary);
6432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6433
6434     MsiCloseHandle(summary);
6435
6436     r = MsiDatabaseCommit(db);
6437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6438
6439     MsiCloseHandle(db);
6440 }
6441
6442 static void test_admin(void)
6443 {
6444     UINT r;
6445
6446     CreateDirectoryA("msitest", NULL);
6447     create_file("msitest\\augustus", 500);
6448
6449     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
6450     set_admin_summary_info(msifile);
6451
6452     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6453
6454     r = MsiInstallProductA(msifile, NULL);
6455     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6456     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6457     ok(!delete_pf("msitest", FALSE), "File installed\n");
6458     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
6459     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
6460
6461     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
6462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6463     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6464     ok(!delete_pf("msitest", FALSE), "File installed\n");
6465     todo_wine
6466     {
6467         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
6468         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
6469     }
6470
6471     DeleteFile(msifile);
6472     DeleteFile("msitest\\augustus");
6473     RemoveDirectory("msitest");
6474 }
6475
6476 static void set_admin_property_stream(LPCSTR file)
6477 {
6478     IStorage *stg;
6479     IStream *stm;
6480     WCHAR fileW[MAX_PATH];
6481     HRESULT hr;
6482     DWORD count;
6483     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
6484
6485     /* AdminProperties */
6486     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
6487     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
6488         'M','y','P','r','o','p','=','4','2',0};
6489
6490     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
6491
6492     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
6493     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6494     if (!stg)
6495         return;
6496
6497     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
6498     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6499
6500     hr = IStream_Write(stm, data, sizeof(data), &count);
6501     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6502
6503     IStream_Release(stm);
6504     IStorage_Release(stg);
6505 }
6506
6507 static void test_adminprops(void)
6508 {
6509     UINT r;
6510
6511     CreateDirectoryA("msitest", NULL);
6512     create_file("msitest\\augustus", 500);
6513
6514     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
6515     set_admin_summary_info(msifile);
6516     set_admin_property_stream(msifile);
6517
6518     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6519
6520     r = MsiInstallProductA(msifile, NULL);
6521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6522     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6523     ok(delete_pf("msitest", FALSE), "File installed\n");
6524
6525     DeleteFile(msifile);
6526     DeleteFile("msitest\\augustus");
6527     RemoveDirectory("msitest");
6528 }
6529
6530 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
6531 {
6532     CHAR path[MAX_PATH];
6533
6534     lstrcpyA(path, PROG_FILES_DIR);
6535     lstrcatA(path, "\\");
6536     lstrcatA(path, file);
6537
6538     if (is_file)
6539         create_file_data(path, data, 500);
6540     else
6541         CreateDirectoryA(path, NULL);
6542 }
6543
6544 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
6545
6546 static void test_removefiles(void)
6547 {
6548     UINT r;
6549
6550     CreateDirectoryA("msitest", NULL);
6551     create_file("msitest\\hydrogen", 500);
6552     create_file("msitest\\helium", 500);
6553     create_file("msitest\\lithium", 500);
6554
6555     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
6556
6557     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6558
6559     r = MsiInstallProductA(msifile, NULL);
6560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6561     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6562     ok(!pf_exists("msitest\\helium"), "File installed\n");
6563     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6564     ok(pf_exists("msitest"), "File not installed\n");
6565
6566     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6568     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6569     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
6570     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6571     ok(delete_pf("msitest", FALSE), "File deleted\n");
6572
6573     create_pf("msitest", FALSE);
6574     create_pf("msitest\\hydrogen", TRUE);
6575     create_pf("msitest\\helium", TRUE);
6576     create_pf("msitest\\lithium", TRUE);
6577
6578     r = MsiInstallProductA(msifile, NULL);
6579     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6580     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6581     ok(pf_exists("msitest\\helium"), "File not installed\n");
6582     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6583     ok(pf_exists("msitest"), "File not installed\n");
6584
6585     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6586     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6587     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6588     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
6589     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6590     ok(delete_pf("msitest", FALSE), "File deleted\n");
6591
6592     create_pf("msitest", FALSE);
6593     create_pf("msitest\\furlong", TRUE);
6594     create_pf("msitest\\firkin", TRUE);
6595     create_pf("msitest\\fortnight", TRUE);
6596     create_pf("msitest\\becquerel", TRUE);
6597     create_pf("msitest\\dioptre", TRUE);
6598     create_pf("msitest\\attoparsec", TRUE);
6599     create_pf("msitest\\storeys", TRUE);
6600     create_pf("msitest\\block", TRUE);
6601     create_pf("msitest\\siriometer", TRUE);
6602     create_pf("msitest\\cabout", FALSE);
6603     create_pf("msitest\\cabout\\blocker", TRUE);
6604
6605     r = MsiInstallProductA(msifile, NULL);
6606     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6607     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6608     ok(!pf_exists("msitest\\helium"), "File installed\n");
6609     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6610     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
6611     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
6612     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
6613     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
6614     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
6615     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
6616     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
6617     ok(!pf_exists("msitest\\block"), "File not deleted\n");
6618     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
6619     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
6620     ok(pf_exists("msitest"), "File not installed\n");
6621
6622     create_pf("msitest\\furlong", TRUE);
6623     create_pf("msitest\\firkin", TRUE);
6624     create_pf("msitest\\fortnight", TRUE);
6625     create_pf("msitest\\storeys", TRUE);
6626     create_pf("msitest\\block", TRUE);
6627     create_pf("msitest\\siriometer", TRUE);
6628
6629     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6630     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6631     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
6632     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
6633     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6634     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
6635     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
6636     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
6637     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
6638     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
6639     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
6640     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
6641     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
6642     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
6643     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6644     ok(pf_exists("msitest"), "Directory deleted\n");
6645
6646     r = MsiInstallProductA(msifile, NULL);
6647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6648     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
6649     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
6650     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
6651     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6652     ok(pf_exists("msitest"), "Directory deleted\n");
6653
6654     delete_pf("msitest\\cabout\\blocker", TRUE);
6655
6656     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6657     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6658     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
6659     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
6660
6661     DeleteFile(msifile);
6662     DeleteFile("msitest\\hydrogen");
6663     DeleteFile("msitest\\helium");
6664     DeleteFile("msitest\\lithium");
6665     RemoveDirectory("msitest");
6666 }
6667
6668 static void test_movefiles(void)
6669 {
6670     UINT r;
6671     char props[MAX_PATH];
6672
6673     CreateDirectoryA("msitest", NULL);
6674     create_file("msitest\\augustus", 100);
6675     create_file("cameroon", 100);
6676     create_file("djibouti", 100);
6677     create_file("egypt", 100);
6678     create_file("finland", 100);
6679     create_file("gambai", 100);
6680     create_file("honduras", 100);
6681     create_file("msitest\\india", 100);
6682     create_file("japan", 100);
6683     create_file("kenya", 100);
6684     CreateDirectoryA("latvia", NULL);
6685     create_file("nauru", 100);
6686     create_file("peru", 100);
6687     create_file("apple", 100);
6688     create_file("application", 100);
6689     create_file("ape", 100);
6690     create_file("foo", 100);
6691     create_file("fao", 100);
6692     create_file("fbod", 100);
6693     create_file("budding", 100);
6694     create_file("buddy", 100);
6695     create_file("bud", 100);
6696     create_file("bar", 100);
6697     create_file("bur", 100);
6698     create_file("bird", 100);
6699
6700     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
6701
6702     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6703
6704     /* if the source or dest property is not a full path,
6705      * windows tries to access it as a network resource
6706      */
6707
6708     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
6709             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
6710             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
6711
6712     r = MsiInstallProductA(msifile, props);
6713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6714     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6715     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
6716     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
6717     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
6718     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
6719     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
6720     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
6721     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
6722     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
6723     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
6724     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
6725     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
6726     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
6727     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
6728     /* either apple or application will be moved depending on directory order */
6729     if (!delete_pf("msitest\\apple", TRUE))
6730         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
6731     else
6732         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
6733     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
6734     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
6735     /* either fao or foo will be moved depending on directory order */
6736     if (delete_pf("msitest\\foo", TRUE))
6737         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
6738     else
6739         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
6740     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
6741     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
6742     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
6743     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
6744     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
6745     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
6746     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
6747     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
6748     ok(delete_pf("msitest", FALSE), "File not installed\n");
6749     ok(DeleteFileA("cameroon"), "File moved\n");
6750     ok(!DeleteFileA("djibouti"), "File not moved\n");
6751     ok(DeleteFileA("egypt"), "File moved\n");
6752     ok(DeleteFileA("finland"), "File moved\n");
6753     ok(DeleteFileA("gambai"), "File moved\n");
6754     ok(!DeleteFileA("honduras"), "File not moved\n");
6755     ok(DeleteFileA("msitest\\india"), "File moved\n");
6756     ok(DeleteFileA("japan"), "File moved\n");
6757     ok(!DeleteFileA("kenya"), "File not moved\n");
6758     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
6759     ok(!DeleteFileA("nauru"), "File not moved\n");
6760     ok(!DeleteFileA("peru"), "File not moved\n");
6761     ok(!DeleteFileA("apple"), "File not moved\n");
6762     ok(!DeleteFileA("application"), "File not moved\n");
6763     ok(DeleteFileA("ape"), "File moved\n");
6764     ok(!DeleteFileA("foo"), "File not moved\n");
6765     ok(!DeleteFileA("fao"), "File not moved\n");
6766     ok(DeleteFileA("fbod"), "File moved\n");
6767     ok(!DeleteFileA("budding"), "File not moved\n");
6768     ok(!DeleteFileA("buddy"), "File not moved\n");
6769     ok(DeleteFileA("bud"), "File moved\n");
6770     ok(!DeleteFileA("bar"), "File not moved\n");
6771     ok(!DeleteFileA("bur"), "File not moved\n");
6772     ok(DeleteFileA("bird"), "File moved\n");
6773
6774     DeleteFile("msitest\\augustus");
6775     RemoveDirectory("msitest");
6776     DeleteFile(msifile);
6777 }
6778
6779 static void test_missingcab(void)
6780 {
6781     UINT r;
6782
6783     CreateDirectoryA("msitest", NULL);
6784     create_file("msitest\\augustus", 500);
6785     create_file("maximus", 500);
6786
6787     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
6788
6789     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6790
6791     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6792
6793     create_pf("msitest", FALSE);
6794     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6795
6796     r = MsiInstallProductA(msifile, NULL);
6797     ok(r == ERROR_SUCCESS ||
6798        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
6799        "Expected ERROR_SUCCESS, got %u\n", r);
6800     if (r == ERROR_SUCCESS)
6801     {
6802       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6803       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6804     }
6805     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
6806     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
6807     ok(delete_pf("msitest", FALSE), "File not installed\n");
6808
6809     create_pf("msitest", FALSE);
6810     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6811     create_pf("msitest\\gaius", TRUE);
6812
6813     r = MsiInstallProductA(msifile, "GAIUS=1");
6814     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6815     todo_wine
6816     {
6817         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
6818         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6819     }
6820     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
6821     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
6822     ok(delete_pf("msitest", FALSE), "File not installed\n");
6823
6824     DeleteFile("msitest\\augustus");
6825     RemoveDirectory("msitest");
6826     DeleteFile("maximus");
6827     DeleteFile("test1.cab");
6828     DeleteFile(msifile);
6829 }
6830
6831 static void test_duplicatefiles(void)
6832 {
6833     UINT r;
6834
6835     CreateDirectoryA("msitest", NULL);
6836     create_file("msitest\\maximus", 500);
6837     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
6838
6839     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6840
6841     /* fails if the destination folder is not a valid property */
6842
6843     r = MsiInstallProductA(msifile, NULL);
6844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6845     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6846     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
6847     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
6848     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
6849     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
6850     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
6851     ok(delete_pf("msitest", FALSE), "File not installed\n");
6852
6853     DeleteFile("msitest\\maximus");
6854     RemoveDirectory("msitest");
6855     DeleteFile(msifile);
6856 }
6857
6858 static void test_writeregistryvalues(void)
6859 {
6860     UINT r;
6861     LONG res;
6862     HKEY hkey;
6863     DWORD type, size;
6864     CHAR path[MAX_PATH];
6865
6866     CreateDirectoryA("msitest", NULL);
6867     create_file("msitest\\augustus", 500);
6868
6869     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
6870
6871     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6872
6873     r = MsiInstallProductA(msifile, NULL);
6874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6875     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6876     ok(delete_pf("msitest", FALSE), "File installed\n");
6877
6878     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
6879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6880
6881     size = MAX_PATH;
6882     type = REG_MULTI_SZ;
6883     memset(path, 'a', MAX_PATH);
6884     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
6885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6886     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
6887     ok(size == 15, "Expected 15, got %d\n", size);
6888     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
6889
6890     DeleteFile(msifile);
6891     DeleteFile("msitest\\augustus");
6892     RemoveDirectory("msitest");
6893
6894     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
6895     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
6896 }
6897
6898 static void test_sourcefolder(void)
6899 {
6900     UINT r;
6901
6902     CreateDirectoryA("msitest", NULL);
6903     create_file("augustus", 500);
6904
6905     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
6906
6907     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6908
6909     r = MsiInstallProductA(msifile, NULL);
6910     ok(r == ERROR_INSTALL_FAILURE,
6911        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6912     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6913     todo_wine
6914     {
6915         ok(!delete_pf("msitest", FALSE), "File installed\n");
6916     }
6917
6918     RemoveDirectoryA("msitest");
6919
6920     r = MsiInstallProductA(msifile, NULL);
6921     ok(r == ERROR_INSTALL_FAILURE,
6922        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6923     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6924     todo_wine
6925     {
6926         ok(!delete_pf("msitest", FALSE), "File installed\n");
6927     }
6928
6929     DeleteFile(msifile);
6930     DeleteFile("augustus");
6931 }
6932
6933 static void test_customaction51(void)
6934 {
6935     UINT r;
6936
6937     CreateDirectoryA("msitest", NULL);
6938     create_file("msitest\\augustus", 500);
6939
6940     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6941
6942     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6943
6944     r = MsiInstallProductA(msifile, NULL);
6945     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6946     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6947     ok(delete_pf("msitest", FALSE), "File installed\n");
6948
6949     DeleteFile(msifile);
6950     DeleteFile("msitest\\augustus");
6951     RemoveDirectory("msitest");
6952 }
6953
6954 static void test_installstate(void)
6955 {
6956     UINT r;
6957
6958     CreateDirectoryA("msitest", NULL);
6959     create_file("msitest\\alpha", 500);
6960     create_file("msitest\\beta", 500);
6961     create_file("msitest\\gamma", 500);
6962     create_file("msitest\\theta", 500);
6963     create_file("msitest\\delta", 500);
6964     create_file("msitest\\epsilon", 500);
6965     create_file("msitest\\zeta", 500);
6966     create_file("msitest\\iota", 500);
6967     create_file("msitest\\eta", 500);
6968     create_file("msitest\\kappa", 500);
6969     create_file("msitest\\lambda", 500);
6970     create_file("msitest\\mu", 500);
6971
6972     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
6973
6974     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6975
6976     r = MsiInstallProductA(msifile, NULL);
6977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6978     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6979     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6980     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6981     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6982     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6983     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6984     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6985     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6986     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6987     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6988     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6989     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6990     ok(delete_pf("msitest", FALSE), "File not installed\n");
6991
6992     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
6993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6994     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6995     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6996     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6997     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6998     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6999     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
7000     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
7001     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
7002     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
7003     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
7004     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
7005     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
7006     ok(delete_pf("msitest", FALSE), "File not installed\n");
7007
7008     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
7009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7010     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
7011     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
7012     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
7013     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
7014     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
7015     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
7016     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
7017     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
7018     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
7019     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
7020     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
7021     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
7022     ok(delete_pf("msitest", FALSE), "File not installed\n");
7023
7024     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
7025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7026     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
7027     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
7028     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
7029     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
7030     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
7031     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
7032     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
7033     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
7034     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
7035     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
7036     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
7037     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
7038     ok(!delete_pf("msitest", FALSE), "File installed\n");
7039
7040     DeleteFile(msifile);
7041     DeleteFile("msitest\\alpha");
7042     DeleteFile("msitest\\beta");
7043     DeleteFile("msitest\\gamma");
7044     DeleteFile("msitest\\theta");
7045     DeleteFile("msitest\\delta");
7046     DeleteFile("msitest\\epsilon");
7047     DeleteFile("msitest\\zeta");
7048     DeleteFile("msitest\\iota");
7049     DeleteFile("msitest\\eta");
7050     DeleteFile("msitest\\kappa");
7051     DeleteFile("msitest\\lambda");
7052     DeleteFile("msitest\\mu");
7053     RemoveDirectory("msitest");
7054 }
7055
7056 struct sourcepathmap
7057 {
7058     BOOL sost; /* shortone\shorttwo */
7059     BOOL solt; /* shortone\longtwo */
7060     BOOL lost; /* longone\shorttwo */
7061     BOOL lolt; /* longone\longtwo */
7062     BOOL soste; /* shortone\shorttwo source exists */
7063     BOOL solte; /* shortone\longtwo source exists */
7064     BOOL loste; /* longone\shorttwo source exists */
7065     BOOL lolte; /* longone\longtwo source exists */
7066     UINT err;
7067     DWORD size;
7068 } spmap[256] =
7069 {
7070     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7071     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7072     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7073     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7074     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7075     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7076     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7077     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7078     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7079     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7080     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7081     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7082     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7083     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7084     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7085     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7086     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7087     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7088     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7089     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7090     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7091     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7092     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7093     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7094     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7095     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7096     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7097     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7098     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7099     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7100     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7101     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7102     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7103     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7104     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7105     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7106     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7107     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7108     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7109     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7110     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7111     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7112     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7113     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7114     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7115     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7116     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7117     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7118     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7119     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7120     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7121     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7122     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7123     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7124     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7125     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7126     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7127     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7128     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7129     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7130     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7131     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7132     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7133     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7134     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7135     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7136     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7137     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7138     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7139     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7140     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7141     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7142     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7143     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7144     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7145     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7146     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7147     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7148     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7149     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7150     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7151     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7152     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7153     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7154     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7155     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7156     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7157     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7158     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7159     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7160     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7161     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7162     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7163     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7164     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7165     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7166     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7167     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7168     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7169     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7170     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7171     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7172     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7173     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7174     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7175     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7176     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7177     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7178     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7179     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7180     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7181     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7182     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7183     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7184     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7185     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7186     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7187     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7188     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7189     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7190     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7191     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7192     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7193     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7194     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7195     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7196     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7197     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7198     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7199     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7200     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7201     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7202     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7203     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7204     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7205     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7206     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7207     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7208     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7209     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7210     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7211     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7212     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7213     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7214     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7215     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7216     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7217     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7218     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7219     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7220     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7221     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7222     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7223     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7224     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7225     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7226     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7227     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7228     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7229     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7230     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7231     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7232     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7233     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7234     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7235     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7236     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7237     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7238     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7239     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7240     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7241     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7242     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7243     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7244     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7245     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7246     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7247     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7248     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7249     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7250     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7251     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7252     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7253     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7254     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7255     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7256     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7257     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7258     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7259     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7260     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7261     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7262     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7263     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7264     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7265     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7266     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7267     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7268     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7269     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7270     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7271     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7272     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7273     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7274     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7275     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7276     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7277     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7278     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7279     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7280     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7281     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7282     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7283     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7284     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7285     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7286     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7287     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7288     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7289     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7290     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7291     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7292     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7293     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7294     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7295     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7296     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7297     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7298     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7299     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7300     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7301     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7302     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7303     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7304     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7305     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7306     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7307     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7308     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7309     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7310     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7311     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7312     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7313     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7314     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7315     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7316     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7317     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7318     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7319     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7320     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7321     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7322     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7323     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7324     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7325     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7326 };
7327
7328 static DWORD get_pf_file_size(LPCSTR file)
7329 {
7330     CHAR path[MAX_PATH];
7331     HANDLE hfile;
7332     DWORD size;
7333
7334     lstrcpyA(path, PROG_FILES_DIR);
7335     lstrcatA(path, "\\");
7336     lstrcatA(path, file);
7337
7338     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7339     if (hfile == INVALID_HANDLE_VALUE)
7340         return INVALID_FILE_SIZE;
7341
7342     size = GetFileSize(hfile, NULL);
7343     CloseHandle(hfile);
7344     return size;
7345 }
7346
7347 static void test_sourcepath(void)
7348 {
7349     UINT r, i;
7350
7351     if (!winetest_interactive)
7352     {
7353         skip("Run in interactive mode to run source path tests.\n");
7354         return;
7355     }
7356
7357     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
7358
7359     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7360
7361     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
7362     {
7363         if (spmap[i].sost)
7364         {
7365             CreateDirectoryA("shortone", NULL);
7366             CreateDirectoryA("shortone\\shorttwo", NULL);
7367         }
7368
7369         if (spmap[i].solt)
7370         {
7371             CreateDirectoryA("shortone", NULL);
7372             CreateDirectoryA("shortone\\longtwo", NULL);
7373         }
7374
7375         if (spmap[i].lost)
7376         {
7377             CreateDirectoryA("longone", NULL);
7378             CreateDirectoryA("longone\\shorttwo", NULL);
7379         }
7380
7381         if (spmap[i].lolt)
7382         {
7383             CreateDirectoryA("longone", NULL);
7384             CreateDirectoryA("longone\\longtwo", NULL);
7385         }
7386
7387         if (spmap[i].soste)
7388             create_file("shortone\\shorttwo\\augustus", 50);
7389         if (spmap[i].solte)
7390             create_file("shortone\\longtwo\\augustus", 100);
7391         if (spmap[i].loste)
7392             create_file("longone\\shorttwo\\augustus", 150);
7393         if (spmap[i].lolte)
7394             create_file("longone\\longtwo\\augustus", 200);
7395
7396         r = MsiInstallProductA(msifile, NULL);
7397         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
7398         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
7399            "%d: Expected %d, got %d\n", i, spmap[i].size,
7400            get_pf_file_size("msitest\\augustus"));
7401
7402         if (r == ERROR_SUCCESS)
7403         {
7404             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
7405             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
7406         }
7407         else
7408         {
7409             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
7410             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
7411         }
7412
7413         DeleteFileA("shortone\\shorttwo\\augustus");
7414         DeleteFileA("shortone\\longtwo\\augustus");
7415         DeleteFileA("longone\\shorttwo\\augustus");
7416         DeleteFileA("longone\\longtwo\\augustus");
7417         RemoveDirectoryA("shortone\\shorttwo");
7418         RemoveDirectoryA("shortone\\longtwo");
7419         RemoveDirectoryA("longone\\shorttwo");
7420         RemoveDirectoryA("longone\\longtwo");
7421         RemoveDirectoryA("shortone");
7422         RemoveDirectoryA("longone");
7423     }
7424
7425     DeleteFileA(msifile);
7426 }
7427
7428 static void test_MsiConfigureProductEx(void)
7429 {
7430     UINT r;
7431     LONG res;
7432     DWORD type, size;
7433     HKEY props, source;
7434     CHAR keypath[MAX_PATH * 2];
7435     CHAR localpack[MAX_PATH];
7436
7437     if (on_win9x)
7438     {
7439         win_skip("Different registry keys on Win9x and WinMe\n");
7440         return;
7441     }
7442
7443     CreateDirectoryA("msitest", NULL);
7444     create_file("msitest\\hydrogen", 500);
7445     create_file("msitest\\helium", 500);
7446     create_file("msitest\\lithium", 500);
7447
7448     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7449
7450     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7451
7452     /* NULL szProduct */
7453     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
7454                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7455     ok(r == ERROR_INVALID_PARAMETER,
7456        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7457
7458     /* empty szProduct */
7459     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
7460                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7461     ok(r == ERROR_INVALID_PARAMETER,
7462        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7463
7464     /* garbage szProduct */
7465     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
7466                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7467     ok(r == ERROR_INVALID_PARAMETER,
7468        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7469
7470     /* guid without brackets */
7471     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7472                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7473                                "PROPVAR=42");
7474     ok(r == ERROR_INVALID_PARAMETER,
7475        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7476
7477     /* guid with brackets */
7478     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7479                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7480                                "PROPVAR=42");
7481     ok(r == ERROR_UNKNOWN_PRODUCT,
7482        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7483
7484     /* same length as guid, but random */
7485     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
7486                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7487                                "PROPVAR=42");
7488     ok(r == ERROR_UNKNOWN_PRODUCT,
7489        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7490
7491     /* product not installed yet */
7492     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7493                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7494                                "PROPVAR=42");
7495     ok(r == ERROR_UNKNOWN_PRODUCT,
7496        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7497
7498     /* install the product, per-user unmanaged */
7499     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7501     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7502     ok(pf_exists("msitest\\helium"), "File not installed\n");
7503     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7504     ok(pf_exists("msitest"), "File not installed\n");
7505
7506     /* product is installed per-user managed, remove it */
7507     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7508                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7509                                "PROPVAR=42");
7510     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7511     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7512     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7513     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7514     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7515
7516     /* product has been removed */
7517     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7518                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7519                                "PROPVAR=42");
7520     ok(r == ERROR_UNKNOWN_PRODUCT,
7521        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7522
7523     /* install the product, machine */
7524     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7525     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7526     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7527     ok(pf_exists("msitest\\helium"), "File not installed\n");
7528     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7529     ok(pf_exists("msitest"), "File not installed\n");
7530
7531     /* product is installed machine, remove it */
7532     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7533                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7534                                "PROPVAR=42");
7535     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7536     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7537     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7538     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7539     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7540
7541     /* product has been removed */
7542     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7543                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7544                                "PROPVAR=42");
7545     ok(r == ERROR_UNKNOWN_PRODUCT,
7546        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7547
7548     /* install the product, machine */
7549     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7551     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7552     ok(pf_exists("msitest\\helium"), "File not installed\n");
7553     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7554     ok(pf_exists("msitest"), "File not installed\n");
7555
7556     DeleteFileA(msifile);
7557
7558     /* local msifile is removed */
7559     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7560                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7561                                "PROPVAR=42");
7562     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7563     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7564     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7565     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7566     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7567
7568     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7569
7570     /* install the product, machine */
7571     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7573     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7574     ok(pf_exists("msitest\\helium"), "File not installed\n");
7575     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7576     ok(pf_exists("msitest"), "File not installed\n");
7577
7578     DeleteFileA(msifile);
7579
7580     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7581     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7582     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7583
7584     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7586
7587     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7588                          (const BYTE *)"C:\\idontexist.msi", 18);
7589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7590
7591     /* LocalPackage is used to find the cached msi package */
7592     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7593                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7594                                "PROPVAR=42");
7595     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7596        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7597     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7598     ok(pf_exists("msitest\\helium"), "File not installed\n");
7599     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7600     ok(pf_exists("msitest"), "File not installed\n");
7601
7602     RegCloseKey(props);
7603     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7604
7605     /* LastUsedSource (local msi package) can be used as a last resort */
7606     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7607                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7608                                "PROPVAR=42");
7609     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7610     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7611     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7612     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7613     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7614
7615     /* install the product, machine */
7616     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7617     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7618     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7619     ok(pf_exists("msitest\\helium"), "File not installed\n");
7620     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7621     ok(pf_exists("msitest"), "File not installed\n");
7622
7623     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7624     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7625     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7626
7627     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7629
7630     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7631                          (const BYTE *)"C:\\idontexist.msi", 18);
7632     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7633
7634     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
7635     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
7636
7637     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
7638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7639
7640     type = REG_SZ;
7641     size = MAX_PATH;
7642     res = RegQueryValueExA(source, "PackageName", NULL, &type,
7643                            (LPBYTE)localpack, &size);
7644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7645
7646     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7647                          (const BYTE *)"idontexist.msi", 15);
7648     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7649
7650     /* SourceList is altered */
7651     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7652                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7653                                "PROPVAR=42");
7654     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7655        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7656     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7657     ok(pf_exists("msitest\\helium"), "File not installed\n");
7658     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7659     ok(pf_exists("msitest"), "File not installed\n");
7660
7661     /* restore the SourceList */
7662     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7663                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
7664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7665
7666     /* finally remove the product */
7667     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7668                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7669                                "PROPVAR=42");
7670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7671     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7672     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7673     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7674     ok(!delete_pf("msitest", FALSE), "File not removed\n");
7675
7676     DeleteFileA(msifile);
7677     RegCloseKey(source);
7678     RegCloseKey(props);
7679     DeleteFileA("msitest\\hydrogen");
7680     DeleteFileA("msitest\\helium");
7681     DeleteFileA("msitest\\lithium");
7682     RemoveDirectoryA("msitest");
7683 }
7684
7685 static void test_missingcomponent(void)
7686 {
7687     UINT r;
7688
7689     CreateDirectoryA("msitest", NULL);
7690     create_file("msitest\\hydrogen", 500);
7691     create_file("msitest\\helium", 500);
7692     create_file("msitest\\lithium", 500);
7693     create_file("beryllium", 500);
7694
7695     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
7696
7697     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7698
7699     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7700     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7701     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7702     ok(pf_exists("msitest\\helium"), "File not installed\n");
7703     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7704     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7705     ok(pf_exists("msitest"), "File not installed\n");
7706
7707     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
7708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7709     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7710     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7711     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7712     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7713     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7714
7715     DeleteFileA(msifile);
7716     DeleteFileA("msitest\\hydrogen");
7717     DeleteFileA("msitest\\helium");
7718     DeleteFileA("msitest\\lithium");
7719     DeleteFileA("beryllium");
7720     RemoveDirectoryA("msitest");
7721 }
7722
7723 static void test_sourcedirprop(void)
7724 {
7725     UINT r;
7726     CHAR props[MAX_PATH];
7727
7728     CreateDirectoryA("msitest", NULL);
7729     create_file("msitest\\augustus", 500);
7730
7731     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
7732
7733     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7734
7735     r = MsiInstallProductA(msifile, NULL);
7736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7737     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7738     ok(delete_pf("msitest", FALSE), "File installed\n");
7739
7740     DeleteFile("msitest\\augustus");
7741     RemoveDirectory("msitest");
7742
7743     CreateDirectoryA("altsource", NULL);
7744     CreateDirectoryA("altsource\\msitest", NULL);
7745     create_file("altsource\\msitest\\augustus", 500);
7746
7747     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
7748
7749     r = MsiInstallProductA(msifile, props);
7750     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7751     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7752     ok(delete_pf("msitest", FALSE), "File installed\n");
7753
7754     DeleteFile(msifile);
7755     DeleteFile("altsource\\msitest\\augustus");
7756     RemoveDirectory("altsource\\msitest");
7757     RemoveDirectory("altsource");
7758 }
7759
7760 static void test_adminimage(void)
7761 {
7762     UINT r;
7763
7764     CreateDirectoryA("msitest", NULL);
7765     CreateDirectoryA("msitest\\first", NULL);
7766     CreateDirectoryA("msitest\\second", NULL);
7767     CreateDirectoryA("msitest\\cabout", NULL);
7768     CreateDirectoryA("msitest\\cabout\\new", NULL);
7769     create_file("msitest\\one.txt", 100);
7770     create_file("msitest\\first\\two.txt", 100);
7771     create_file("msitest\\second\\three.txt", 100);
7772     create_file("msitest\\cabout\\four.txt", 100);
7773     create_file("msitest\\cabout\\new\\five.txt", 100);
7774     create_file("msitest\\filename", 100);
7775     create_file("msitest\\service.exe", 100);
7776
7777     create_database_wordcount(msifile, ai_tables,
7778                               sizeof(ai_tables) / sizeof(msi_table),
7779                               msidbSumInfoSourceTypeAdminImage);
7780
7781     r = MsiInstallProductA(msifile, NULL);
7782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7783
7784     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7785     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7786     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7787     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7788     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7789     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7790     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7791     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7792     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7793     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7794     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7795     ok(delete_pf("msitest", FALSE), "File not installed\n");
7796
7797     DeleteFileA("msitest.msi");
7798     DeleteFileA("msitest\\cabout\\new\\five.txt");
7799     DeleteFileA("msitest\\cabout\\four.txt");
7800     DeleteFileA("msitest\\second\\three.txt");
7801     DeleteFileA("msitest\\first\\two.txt");
7802     DeleteFileA("msitest\\one.txt");
7803     DeleteFileA("msitest\\service.exe");
7804     DeleteFileA("msitest\\filename");
7805     RemoveDirectoryA("msitest\\cabout\\new");
7806     RemoveDirectoryA("msitest\\cabout");
7807     RemoveDirectoryA("msitest\\second");
7808     RemoveDirectoryA("msitest\\first");
7809     RemoveDirectoryA("msitest");
7810 }
7811
7812 static void test_propcase(void)
7813 {
7814     UINT r;
7815
7816     CreateDirectoryA("msitest", NULL);
7817     create_file("msitest\\augustus", 500);
7818
7819     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
7820
7821     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7822
7823     r = MsiInstallProductA(msifile, "MyProp=42");
7824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7825     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
7826     ok(delete_pf("msitest", FALSE), "File not installed\n");
7827
7828     DeleteFile(msifile);
7829     DeleteFile("msitest\\augustus");
7830     RemoveDirectory("msitest");
7831 }
7832
7833 static void test_int_widths( void )
7834 {
7835     static const char int0[] = "int0\ni0\nint0\tint0\n1";
7836     static const char int1[] = "int1\ni1\nint1\tint1\n1";
7837     static const char int2[] = "int2\ni2\nint2\tint2\n1";
7838     static const char int3[] = "int3\ni3\nint3\tint3\n1";
7839     static const char int4[] = "int4\ni4\nint4\tint4\n1";
7840     static const char int5[] = "int5\ni5\nint5\tint5\n1";
7841     static const char int8[] = "int8\ni8\nint8\tint8\n1";
7842
7843     static const struct
7844     {
7845         const char  *data;
7846         unsigned int size;
7847         UINT         ret;
7848     }
7849     tests[] =
7850     {
7851         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
7852         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
7853         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
7854         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
7855         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
7856         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
7857         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
7858     };
7859
7860     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
7861     MSIHANDLE db;
7862     UINT r, i;
7863
7864     GetTempPathA(MAX_PATH, tmpdir);
7865     CreateDirectoryA(tmpdir, NULL);
7866
7867     strcpy(msitable, tmpdir);
7868     strcat(msitable, "\\msitable.idt");
7869
7870     strcpy(msidb, tmpdir);
7871     strcat(msidb, "\\msitest.msi");
7872
7873     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
7874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7875
7876     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
7877     {
7878         write_file(msitable, tests[i].data, tests[i].size);
7879
7880         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
7881         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
7882
7883         r = MsiDatabaseCommit(db);
7884         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7885         DeleteFileA(msitable);
7886     }
7887
7888     MsiCloseHandle(db);
7889     DeleteFileA(msidb);
7890     RemoveDirectoryA(tmpdir);
7891 }
7892
7893 static void test_shortcut(void)
7894 {
7895     UINT r;
7896     HRESULT hr;
7897
7898     create_test_files();
7899     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
7900
7901     r = MsiInstallProductA(msifile, NULL);
7902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7903
7904     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
7905     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7906
7907     r = MsiInstallProductA(msifile, NULL);
7908     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7909
7910     CoUninitialize();
7911
7912     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7913     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7914
7915     r = MsiInstallProductA(msifile, NULL);
7916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7917
7918     CoUninitialize();
7919
7920     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7921     delete_pf("msitest\\cabout\\new", FALSE);
7922     delete_pf("msitest\\cabout\\four.txt", TRUE);
7923     delete_pf("msitest\\cabout", FALSE);
7924     delete_pf("msitest\\changed\\three.txt", TRUE);
7925     delete_pf("msitest\\changed", FALSE);
7926     delete_pf("msitest\\first\\two.txt", TRUE);
7927     delete_pf("msitest\\first", FALSE);
7928     delete_pf("msitest\\filename", TRUE);
7929     delete_pf("msitest\\one.txt", TRUE);
7930     delete_pf("msitest\\service.exe", TRUE);
7931     delete_pf("msitest\\Shortcut.lnk", TRUE);
7932     delete_pf("msitest", FALSE);
7933     delete_test_files();
7934 }
7935
7936 static void test_envvar(void)
7937 {
7938     UINT r;
7939     HKEY env;
7940     LONG res;
7941     DWORD type, size;
7942     char buffer[16];
7943     UINT i;
7944
7945     if (on_win9x)
7946     {
7947         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
7948         return;
7949     }
7950
7951     create_test_files();
7952     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
7953
7954     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
7955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7956
7957     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
7958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7959
7960     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
7961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7962
7963     r = MsiInstallProductA(msifile, NULL);
7964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7965
7966     type = REG_NONE;
7967     size = sizeof(buffer);
7968     buffer[0] = 0;
7969     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
7970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7971     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7972     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7973
7974     res = RegDeleteValueA(env, "MSITESTVAR1");
7975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7976
7977     type = REG_NONE;
7978     size = sizeof(buffer);
7979     buffer[0] = 0;
7980     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
7981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7982     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7983     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7984
7985     res = RegDeleteValueA(env, "MSITESTVAR2");
7986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7987
7988     res = RegDeleteValueA(env, "MSITESTVAR3");
7989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7990
7991     res = RegDeleteValueA(env, "MSITESTVAR4");
7992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7993
7994     res = RegDeleteValueA(env, "MSITESTVAR5");
7995     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7996
7997     res = RegDeleteValueA(env, "MSITESTVAR6");
7998     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7999
8000     res = RegDeleteValueA(env, "MSITESTVAR7");
8001     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8002
8003     res = RegDeleteValueA(env, "MSITESTVAR8");
8004     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8005
8006     res = RegDeleteValueA(env, "MSITESTVAR9");
8007     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8008
8009     res = RegDeleteValueA(env, "MSITESTVAR10");
8010     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8011
8012     i = 11;
8013     while (environment_dat_results[(i-11)]) {
8014         char name[20];
8015         sprintf(name, "MSITESTVAR%d", i);
8016
8017         type = REG_NONE;
8018         size = sizeof(buffer);
8019         buffer[0] = 0;
8020         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
8021         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
8022         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
8023         ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n",
8024            i, environment_dat_results[(i-11)], buffer);
8025
8026         res = RegDeleteValueA(env, name);
8027         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
8028         i++;
8029     }
8030
8031
8032     RegCloseKey(env);
8033     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
8034     delete_pf("msitest\\cabout\\new", FALSE);
8035     delete_pf("msitest\\cabout\\four.txt", TRUE);
8036     delete_pf("msitest\\cabout", FALSE);
8037     delete_pf("msitest\\changed\\three.txt", TRUE);
8038     delete_pf("msitest\\changed", FALSE);
8039     delete_pf("msitest\\first\\two.txt", TRUE);
8040     delete_pf("msitest\\first", FALSE);
8041     delete_pf("msitest\\filename", TRUE);
8042     delete_pf("msitest\\one.txt", TRUE);
8043     delete_pf("msitest\\service.exe", TRUE);
8044     delete_pf("msitest", FALSE);
8045     delete_test_files();
8046 }
8047
8048 static void test_preselected(void)
8049 {
8050     UINT r;
8051
8052     create_test_files();
8053     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
8054
8055     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
8056     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8057
8058     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8059     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
8060     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8061     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
8062     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8063     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
8064     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8065     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
8066     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8067     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8068     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8069     ok(delete_pf("msitest", FALSE), "File not installed\n");
8070
8071     r = MsiInstallProductA(msifile, NULL);
8072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8073
8074     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8075     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8076     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8077     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8078     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8079     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8080     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8081     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8082     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8083     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8084     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8085     ok(delete_pf("msitest", FALSE), "File not installed\n");
8086     delete_test_files();
8087 }
8088
8089 static void test_installed_prop(void)
8090 {
8091     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
8092     UINT r;
8093
8094     create_test_files();
8095     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
8096
8097     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8098
8099     r = MsiInstallProductA(msifile, "FULL=1");
8100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8101
8102     r = MsiInstallProductA(msifile, "FULL=1");
8103     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8104
8105     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
8106     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8107
8108     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8109     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8110     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8111     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8112     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8113     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8114     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8115     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8116     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8117     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8118     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8119     ok(delete_pf("msitest", FALSE), "File not installed\n");
8120
8121     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8122     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8123
8124     delete_test_files();
8125 }
8126
8127 static void test_allusers_prop(void)
8128 {
8129     UINT r;
8130
8131     create_test_files();
8132     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
8133
8134     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8135
8136     /* ALLUSERS property unset */
8137     r = MsiInstallProductA(msifile, "FULL=1");
8138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8139
8140     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8141     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8142     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8143     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8144     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8145     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8146     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8147     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8148     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8149     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8150     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8151     ok(delete_pf("msitest", FALSE), "File not installed\n");
8152
8153     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8154     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8155
8156     delete_test_files();
8157
8158     create_test_files();
8159     create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
8160
8161     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8162
8163     /* ALLUSERS property set to 1 */
8164     r = MsiInstallProductA(msifile, "FULL=1");
8165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8166
8167     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8168     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8169     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8170     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8171     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8172     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8173     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8174     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8175     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8176     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8177     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8178     ok(delete_pf("msitest", FALSE), "File not installed\n");
8179
8180     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8182
8183     delete_test_files();
8184
8185     create_test_files();
8186     create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
8187
8188     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8189
8190     /* ALLUSERS property set to 2 */
8191     r = MsiInstallProductA(msifile, "FULL=1");
8192     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8193
8194     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8195     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8196     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8197     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8198     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8199     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8200     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8201     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8202     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8203     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8204     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8205     ok(delete_pf("msitest", FALSE), "File not installed\n");
8206
8207     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8208     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8209
8210     delete_test_files();
8211
8212     create_test_files();
8213     create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
8214
8215     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8216
8217     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
8218     r = MsiInstallProductA(msifile, "FULL=1");
8219     if (r == ERROR_SUCCESS)
8220     {
8221         /* Win9x/WinMe */
8222         win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n");
8223
8224         ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8225         ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8226         ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8227         ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8228         ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8229         ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8230         ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8231         ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8232         ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8233         ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8234         ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8235         ok(delete_pf("msitest", FALSE), "File not installed\n");
8236
8237         r = MsiInstallProductA(msifile, "REMOVE=ALL");
8238         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8239
8240         delete_test_files();
8241     }
8242     else
8243         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8244 }
8245
8246 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
8247 static char rename_ops[]      = "PendingFileRenameOperations";
8248
8249 static void process_pending_renames(HKEY hkey)
8250 {
8251     char *buf, *src, *dst, *buf2, *buf2ptr;
8252     DWORD size, buf2len = 0;
8253     LONG ret;
8254     BOOL found = FALSE;
8255
8256     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
8257     buf = HeapAlloc(GetProcessHeap(), 0, size);
8258     buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
8259     buf[0] = 0;
8260
8261     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
8262     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
8263
8264     for (src = buf; *src; src = dst + strlen(dst) + 1)
8265     {
8266         DWORD flags = MOVEFILE_COPY_ALLOWED;
8267
8268         dst = src + strlen(src) + 1;
8269
8270         if (!strstr(src, "msitest"))
8271         {
8272             lstrcpyA(buf2ptr, src);
8273             buf2len += strlen(src) + 1;
8274             buf2ptr += strlen(src) + 1;
8275             if (*dst)
8276             {
8277                 lstrcpyA(buf2ptr, dst);
8278                 buf2ptr += strlen(dst) + 1;
8279                 buf2len += strlen(dst) + 1;
8280             }
8281             buf2ptr++;
8282             buf2len++;
8283             continue;
8284         }
8285
8286         found = TRUE;
8287
8288         if (*dst == '!')
8289         {
8290             flags |= MOVEFILE_REPLACE_EXISTING;
8291             dst++;
8292         }
8293         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
8294         if (*dst)
8295         {
8296             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
8297             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
8298         }
8299         else
8300             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
8301     }
8302
8303     ok(found, "Expected a 'msitest' entry\n");
8304
8305     if (*buf2)
8306     {
8307         buf2len++;
8308         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len);
8309     }
8310     else
8311         RegDeleteValueA(hkey, rename_ops);
8312
8313     HeapFree(GetProcessHeap(), 0, buf);
8314     HeapFree(GetProcessHeap(), 0, buf2);
8315 }
8316
8317 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
8318 {
8319     DWORD len, data_len = strlen(data);
8320     HANDLE handle;
8321     char buf[128];
8322
8323     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
8324     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
8325
8326     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
8327     {
8328         CloseHandle(handle);
8329         return !memcmp(buf, data, data_len);
8330     }
8331     CloseHandle(handle);
8332     return FALSE;
8333 }
8334
8335 static void test_file_in_use(void)
8336 {
8337     UINT r;
8338     HANDLE file;
8339     HKEY hkey;
8340     char path[MAX_PATH];
8341
8342     if (on_win9x)
8343     {
8344         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
8345         return;
8346     }
8347
8348     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
8349
8350     CreateDirectoryA("msitest", NULL);
8351     create_file("msitest\\maximus", 500);
8352     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
8353
8354     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8355
8356     lstrcpy(path, PROG_FILES_DIR);
8357     lstrcat(path, "\\msitest");
8358     CreateDirectoryA(path, NULL);
8359
8360     lstrcat(path, "\\maximus");
8361     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8362
8363     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8364     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8365     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8366     CloseHandle(file);
8367     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8368
8369     process_pending_renames(hkey);
8370     RegCloseKey(hkey);
8371
8372     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
8373     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8374     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8375
8376     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8378
8379     DeleteFileA("msitest\\maximus");
8380     delete_test_files();
8381 }
8382
8383 static void test_file_in_use_cab(void)
8384 {
8385     UINT r;
8386     HANDLE file;
8387     HKEY hkey;
8388     char path[MAX_PATH];
8389
8390     if (on_win9x)
8391     {
8392         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
8393         return;
8394     }
8395
8396     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
8397
8398     CreateDirectoryA("msitest", NULL);
8399     create_file("maximus", 500);
8400     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
8401     DeleteFile("maximus");
8402
8403     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
8404
8405     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8406
8407     lstrcpy(path, PROG_FILES_DIR);
8408     lstrcat(path, "\\msitest");
8409     CreateDirectoryA(path, NULL);
8410
8411     lstrcat(path, "\\maximus");
8412     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8413
8414     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8415     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8416     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8417     CloseHandle(file);
8418     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8419
8420     process_pending_renames(hkey);
8421     RegCloseKey(hkey);
8422
8423     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
8424     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8425     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8426
8427     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8429
8430     delete_cab_files();
8431     delete_test_files();
8432 }
8433
8434 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
8435 {
8436     return IDOK;
8437 }
8438
8439 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
8440 {
8441     return IDOK;
8442 }
8443
8444 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
8445 {
8446     return IDOK;
8447 }
8448
8449 static void test_MsiSetExternalUI(void)
8450 {
8451     INSTALLUI_HANDLERA ret_a;
8452     INSTALLUI_HANDLERW ret_w;
8453     INSTALLUI_HANDLER_RECORD prev;
8454     UINT error;
8455
8456     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8457     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8458
8459     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8460     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
8461
8462     /* Not present before Installer 3.1 */
8463     if (!pMsiSetExternalUIRecord) {
8464         win_skip("MsiSetExternalUIRecord is not available\n");
8465         return;
8466     }
8467
8468     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8469     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8470     ok(prev == NULL, "expected NULL, got %p\n", prev);
8471
8472     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8473     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
8474     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8475     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8476
8477     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8478     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8479
8480     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8481     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
8482
8483     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8484     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8485
8486     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8487     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8488
8489     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8490     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8491     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8492     ok(prev == NULL, "expected NULL, got %p\n", prev);
8493
8494     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8495     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8496
8497     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8498     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8499
8500     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8501     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
8502     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8503     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8504
8505     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
8506     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8507
8508     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
8509     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8510 }
8511
8512 static void test_feature_override(void)
8513 {
8514     UINT r;
8515
8516     create_test_files();
8517     create_file("msitest\\override.txt", 1000);
8518     create_file("msitest\\preselected.txt", 1000);
8519     create_file("msitest\\notpreselected.txt", 1000);
8520     create_database(msifile, fo_tables, sizeof(fo_tables) / sizeof(msi_table));
8521
8522     r = MsiInstallProductA(msifile, "ADDLOCAL=override");
8523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8524
8525     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
8526     ok(!pf_exists("msitest\\preselected.txt"), "file installed\n");
8527     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
8528
8529     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8531
8532     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
8533
8534     r = MsiInstallProductA(msifile, "preselect=1");
8535     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8536
8537     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
8538     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
8539     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
8540
8541     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8543
8544     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
8545     todo_wine {
8546     ok(delete_pf("msitest\\preselected.txt", TRUE), "file removed\n");
8547     ok(delete_pf("msitest", FALSE), "directory removed\n");
8548     }
8549
8550     r = MsiInstallProductA(msifile, NULL);
8551     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8552
8553     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
8554     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
8555     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
8556
8557     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8558     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8559
8560     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
8561     todo_wine {
8562     ok(delete_pf("msitest\\preselected.txt", TRUE), "file removed\n");
8563     ok(delete_pf("msitest", FALSE), "directory removed\n");
8564     }
8565
8566     DeleteFileA("msitest\\override.txt");
8567     DeleteFileA("msitest\\preselected.txt");
8568     DeleteFileA("msitest\\notpreselected.txt");
8569     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest");
8570     delete_test_files();
8571 }
8572
8573 static void test_create_folder(void)
8574 {
8575     UINT r;
8576
8577     create_test_files();
8578     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
8579
8580     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8581
8582     r = MsiInstallProductA(msifile, NULL);
8583     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8584
8585     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8586     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8587     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8588     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8589     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8590     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8591     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8592     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8593     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8594     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8595     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8596     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8597
8598     r = MsiInstallProductA(msifile, "LOCAL=Two");
8599     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8600
8601     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8602     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8603     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8604     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8605     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8606     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8607     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8608     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8609     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8610     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8611     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8612     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8613
8614     delete_test_files();
8615 }
8616
8617 static void test_remove_folder(void)
8618 {
8619     UINT r;
8620
8621     create_test_files();
8622     create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table));
8623
8624     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8625
8626     r = MsiInstallProductA(msifile, NULL);
8627     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8628
8629     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8630     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8631     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8632     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8633     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8634     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8635     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8636     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8637     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8638     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8639     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8640     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8641
8642     r = MsiInstallProductA(msifile, "LOCAL=Two");
8643     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8644
8645     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8646     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8647     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8648     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8649     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8650     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8651     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8652     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8653     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8654     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8655     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8656     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8657
8658     delete_test_files();
8659 }
8660
8661 static void test_start_services(void)
8662 {
8663     UINT r;
8664     SC_HANDLE scm, service;
8665     BOOL ret;
8666     DWORD error = ERROR_SUCCESS;
8667
8668     if (on_win9x)
8669     {
8670         win_skip("Services are not implemented on Win9x and WinMe\n");
8671         return;
8672     }
8673     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8674     ok(scm != NULL, "Failed to open the SC Manager\n");
8675     if (!scm) return;
8676
8677     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8678     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
8679     {
8680         win_skip("The 'Spooler' service does not exist\n");
8681         CloseServiceHandle(scm);
8682         return;
8683     }
8684     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
8685     if (!service) {
8686         CloseServiceHandle(scm);
8687         return;
8688     }
8689
8690     ret = StartService(service, 0, NULL);
8691     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
8692     {
8693         skip("Terminal service not available, skipping test\n");
8694         CloseServiceHandle(service);
8695         CloseServiceHandle(scm);
8696         return;
8697     }
8698
8699     CloseServiceHandle(service);
8700     CloseServiceHandle(scm);
8701
8702     create_test_files();
8703     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
8704
8705     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8706
8707     r = MsiInstallProductA(msifile, NULL);
8708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8709
8710     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8711     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8712     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8713     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8714     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8715     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8716     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8717     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8718     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8719     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8720     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8721     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8722
8723     delete_test_files();
8724
8725     if (error == ERROR_SUCCESS)
8726     {
8727         SERVICE_STATUS status;
8728
8729         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8730         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8731
8732         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
8733         ok(ret, "ControlService failed %u\n", GetLastError());
8734
8735         CloseServiceHandle(service);
8736         CloseServiceHandle(scm);
8737     }
8738 }
8739
8740 static void test_delete_services(void)
8741 {
8742     UINT r;
8743
8744     create_test_files();
8745     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
8746
8747     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8748
8749     r = MsiInstallProductA(msifile, NULL);
8750     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8751
8752     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8753     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8754     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8755     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8756     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8757     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8758     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8759     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8760     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8761     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8762     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8763     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8764
8765     delete_test_files();
8766 }
8767
8768 static void test_self_registration(void)
8769 {
8770     UINT r;
8771
8772     create_test_files();
8773     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
8774
8775     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8776
8777     r = MsiInstallProductA(msifile, NULL);
8778     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8779
8780     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8781     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8782     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8783     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8784     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8785     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8786     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8787     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8788     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8789     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8790     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8791     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8792
8793     delete_test_files();
8794 }
8795
8796 static void test_register_font(void)
8797 {
8798     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
8799     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
8800     LONG ret;
8801     HKEY key;
8802     UINT r;
8803
8804     create_test_files();
8805     create_file("msitest\\font.ttf", 1000);
8806     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
8807
8808     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8809
8810     r = MsiInstallProductA(msifile, NULL);
8811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8812
8813     ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key);
8814     if (ret)
8815         RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key);
8816
8817     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8818     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8819
8820     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8821     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8822
8823     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8824
8825     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8826     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8827
8828     RegDeleteValueA(key, "msi test font");
8829     RegCloseKey(key);
8830     DeleteFileA("msitest\\font.ttf");
8831     delete_test_files();
8832 }
8833
8834 static void test_validate_product_id(void)
8835 {
8836     UINT r;
8837
8838     create_test_files();
8839     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
8840
8841     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8842
8843     r = MsiInstallProductA(msifile, NULL);
8844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8845
8846     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
8847     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8848
8849     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
8850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8851
8852     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
8853     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8854
8855     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8856     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8857     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8858     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8859     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8860     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8861     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8862     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8863     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8864     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8865     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8866     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8867
8868     delete_test_files();
8869 }
8870
8871 static void test_install_remove_odbc(void)
8872 {
8873     UINT r;
8874
8875     create_test_files();
8876     create_file("msitest\\ODBCdriver.dll", 1000);
8877     create_file("msitest\\ODBCdriver2.dll", 1000);
8878     create_file("msitest\\ODBCtranslator.dll", 1000);
8879     create_file("msitest\\ODBCtranslator2.dll", 1000);
8880     create_file("msitest\\ODBCsetup.dll", 1000);
8881     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
8882
8883     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8884
8885     r = MsiInstallProductA(msifile, NULL);
8886     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8887
8888     ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n");
8889     ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n");
8890     ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n");
8891     ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n");
8892     ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n");
8893
8894     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8895     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8896
8897     ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n");
8898     ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n");
8899     ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n");
8900     ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n");
8901     ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n");
8902     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8903
8904     DeleteFileA("msitest\\ODBCdriver.dll");
8905     DeleteFileA("msitest\\ODBCdriver2.dll");
8906     DeleteFileA("msitest\\ODBCtranslator.dll");
8907     DeleteFileA("msitest\\ODBCtranslator2.dll");
8908     DeleteFileA("msitest\\ODBCsetup.dll");
8909     delete_test_files();
8910 }
8911
8912 static void test_register_typelib(void)
8913 {
8914     UINT r;
8915
8916     create_test_files();
8917     create_file("msitest\\typelib.dll", 1000);
8918     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
8919
8920     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8921
8922     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
8923     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8924
8925     r = MsiInstallProductA(msifile, NULL);
8926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8927
8928     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8929     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8930
8931     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
8932     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8933
8934     DeleteFileA("msitest\\typelib.dll");
8935     delete_test_files();
8936 }
8937
8938 static void test_create_remove_shortcut(void)
8939 {
8940     UINT r;
8941
8942     create_test_files();
8943     create_file("msitest\\target.txt", 1000);
8944     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
8945
8946     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8947
8948     r = MsiInstallProductA(msifile, NULL);
8949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8950
8951     ok(pf_exists("msitest\\target.txt"), "file not created\n");
8952     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
8953
8954     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8955     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8956
8957     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
8958     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
8959     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8960
8961     DeleteFileA("msitest\\target.txt");
8962     delete_test_files();
8963 }
8964
8965 static void test_publish_components(void)
8966 {
8967     static char keypath[] =
8968         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
8969
8970     UINT r;
8971     LONG res;
8972     HKEY key;
8973
8974     create_test_files();
8975     create_file("msitest\\english.txt", 1000);
8976     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
8977
8978     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8979
8980     r = MsiInstallProductA(msifile, NULL);
8981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8982
8983     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8984     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
8985
8986     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
8987     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
8988     RegCloseKey(key);
8989
8990     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8992
8993     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8994     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
8995
8996     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
8997     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8998
8999     DeleteFileA("msitest\\english.txt");
9000     delete_test_files();
9001 }
9002
9003 static void test_remove_duplicate_files(void)
9004 {
9005     UINT r;
9006
9007     create_test_files();
9008     create_file("msitest\\original.txt", 1000);
9009     create_file("msitest\\original2.txt", 1000);
9010     create_file("msitest\\original3.txt", 1000);
9011     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
9012
9013     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9014
9015     r = MsiInstallProductA(msifile, NULL);
9016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9017
9018     ok(pf_exists("msitest\\original.txt"), "file not created\n");
9019     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
9020     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
9021     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
9022     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
9023
9024     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9026
9027     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
9028     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
9029     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
9030     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
9031     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
9032     ok(delete_pf("msitest", FALSE), "directory removed\n");
9033
9034     DeleteFileA("msitest\\original.txt");
9035     DeleteFileA("msitest\\original2.txt");
9036     DeleteFileA("msitest\\original3.txt");
9037     delete_test_files();
9038 }
9039
9040 static void test_remove_registry_values(void)
9041 {
9042     UINT r;
9043     LONG res;
9044     HKEY key;
9045
9046     create_test_files();
9047     create_file("msitest\\registry.txt", 1000);
9048     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
9049
9050     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9051
9052     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
9053     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
9054     RegCloseKey(key);
9055
9056     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9057     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
9058     RegCloseKey(key);
9059
9060     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
9061     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
9062     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
9063     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
9064     RegCloseKey(key);
9065
9066     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
9067     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
9068     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
9069     RegCloseKey(key);
9070
9071     r = MsiInstallProductA(msifile, NULL);
9072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9073
9074     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
9075     ok(res == ERROR_SUCCESS, "key removed\n");
9076     RegCloseKey(key);
9077
9078     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9079     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9080
9081     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9083     RegCloseKey(key);
9084
9085     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9086     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9087
9088     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
9089     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9090
9091     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9092     ok(res == ERROR_SUCCESS, "key removed\n");
9093     RegCloseKey(key);
9094
9095     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
9096     ok(res == ERROR_SUCCESS, "key removed\n");
9097     RegCloseKey(key);
9098
9099     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
9100     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9101
9102     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA");
9103     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2");
9104     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine");
9105
9106     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
9107     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9108
9109     DeleteFileA("msitest\\registry.txt");
9110     delete_test_files();
9111 }
9112
9113 static void test_find_related_products(void)
9114 {
9115     UINT r;
9116
9117     create_test_files();
9118     create_file("msitest\\product.txt", 1000);
9119     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
9120
9121     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9122
9123     r = MsiInstallProductA(msifile, NULL);
9124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9125
9126     /* install again, so it finds the upgrade code */
9127     r = MsiInstallProductA(msifile, NULL);
9128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9129
9130     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9132
9133     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
9134     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9135
9136     DeleteFileA("msitest\\product.txt");
9137     delete_test_files();
9138 }
9139
9140 static void test_remove_ini_values(void)
9141 {
9142     UINT r;
9143     DWORD len;
9144     char inifile[MAX_PATH], buf[0x10];
9145     HANDLE file;
9146     BOOL ret;
9147
9148     create_test_files();
9149     create_file("msitest\\inifile.txt", 1000);
9150     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
9151
9152     lstrcpyA(inifile, PROG_FILES_DIR);
9153     lstrcatA(inifile, "\\msitest");
9154     CreateDirectoryA(inifile, NULL);
9155     lstrcatA(inifile, "\\test.ini");
9156     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
9157     CloseHandle(file);
9158
9159     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
9160     ok(ret, "failed to write profile string %u\n", GetLastError());
9161
9162     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
9163     ok(ret, "failed to write profile string %u\n", GetLastError());
9164
9165     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9166
9167     r = MsiInstallProductA(msifile, NULL);
9168     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9169
9170     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
9171     ok(len == 6, "got %u expected 6\n", len);
9172
9173     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
9174     ok(!len, "got %u expected 0\n", len);
9175
9176     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9178
9179     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
9180     ok(!len, "got %u expected 0\n", len);
9181
9182     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
9183     ok(!len, "got %u expected 0\n", len);
9184
9185     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
9186     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
9187     ok(delete_pf("msitest", FALSE), "directory removed\n");
9188
9189     DeleteFileA("msitest\\inifile.txt");
9190     delete_test_files();
9191 }
9192
9193 static void test_remove_env_strings(void)
9194 {
9195     UINT r;
9196     LONG res;
9197     HKEY key;
9198     DWORD type, size;
9199     char buffer[0x10];
9200
9201     if (on_win9x)
9202     {
9203         win_skip("Environment variables are handled differently on win9x and winme\n");
9204         return;
9205     }
9206
9207     create_test_files();
9208     create_file("msitest\\envvar.txt", 1000);
9209     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
9210
9211     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9212
9213     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
9214     ok(!res, "failed to open environment key %d\n", res);
9215
9216     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
9217     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
9218     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
9219     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
9220     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
9221
9222     RegCloseKey(key);
9223
9224     r = MsiInstallProductA(msifile, NULL);
9225     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9226
9227     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
9228     ok(!res, "failed to open environment key %d\n", res);
9229
9230     type = REG_NONE;
9231     buffer[0] = 0;
9232     size = sizeof(buffer);
9233     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
9234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9235     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9236     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9237
9238     type = REG_NONE;
9239     buffer[0] = 0;
9240     size = sizeof(buffer);
9241     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
9242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9243     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9244     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9245
9246     type = REG_NONE;
9247     buffer[0] = 0;
9248     size = sizeof(buffer);
9249     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
9250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9251     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9252     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9253
9254     type = REG_NONE;
9255     buffer[0] = 0;
9256     size = sizeof(buffer);
9257     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
9258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9259     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9260     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9261
9262     type = REG_NONE;
9263     buffer[0] = 0;
9264     size = sizeof(buffer);
9265     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
9266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9267     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9268     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9269
9270     RegCloseKey(key);
9271
9272     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9274
9275     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
9276     ok(!res, "failed to open environment key %d\n", res);
9277
9278     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
9279     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9280
9281     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
9282     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9283
9284     type = REG_NONE;
9285     buffer[0] = 0;
9286     size = sizeof(buffer);
9287     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
9288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9289     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9290     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9291     RegDeleteValueA(key, "MSITESTVAR3");
9292
9293     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
9294     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9295
9296     type = REG_NONE;
9297     buffer[0] = 0;
9298     size = sizeof(buffer);
9299     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
9300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9301     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9302     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9303     RegDeleteValueA(key, "MSITESTVAR5");
9304
9305     RegCloseKey(key);
9306
9307     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
9308     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9309
9310     DeleteFileA("msitest\\envvar.txt");
9311     delete_test_files();
9312 }
9313
9314 static void test_register_class_info(void)
9315 {
9316     UINT r;
9317     LONG res;
9318     HKEY hkey;
9319
9320     create_test_files();
9321     create_file("msitest\\class.txt", 1000);
9322     create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table));
9323
9324     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9325
9326     r = MsiInstallProductA(msifile, NULL);
9327     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9328
9329     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9330     ok(res == ERROR_SUCCESS, "key not created\n");
9331     RegCloseKey(hkey);
9332
9333     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9334     ok(res == ERROR_SUCCESS, "key not created\n");
9335     RegCloseKey(hkey);
9336
9337     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
9338     ok(res == ERROR_SUCCESS, "key not created\n");
9339     RegCloseKey(hkey);
9340
9341     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9343
9344     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9345     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9346
9347     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9348     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9349
9350     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
9351     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9352
9353     ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n");
9354     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9355
9356     DeleteFileA("msitest\\class.txt");
9357     delete_test_files();
9358 }
9359
9360 static void test_register_extension_info(void)
9361 {
9362     UINT r;
9363     LONG res;
9364     HKEY hkey;
9365
9366     create_test_files();
9367     create_file("msitest\\extension.txt", 1000);
9368     create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table));
9369
9370     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9371
9372     r = MsiInstallProductA(msifile, NULL);
9373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9374
9375     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
9376     ok(res == ERROR_SUCCESS, "key not created\n");
9377     RegCloseKey(hkey);
9378
9379     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey);
9380     ok(res == ERROR_SUCCESS, "key not created\n");
9381     RegCloseKey(hkey);
9382
9383     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9384     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9385
9386     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
9387     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9388
9389     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey);
9390     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9391
9392     ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n");
9393     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9394
9395     DeleteFileA("msitest\\extension.txt");
9396     delete_test_files();
9397 }
9398
9399 static void test_register_mime_info(void)
9400 {
9401     UINT r;
9402     LONG res;
9403     HKEY hkey;
9404
9405     create_test_files();
9406     create_file("msitest\\mime.txt", 1000);
9407     create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table));
9408
9409     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9410
9411     r = MsiInstallProductA(msifile, NULL);
9412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9413
9414     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
9415     ok(res == ERROR_SUCCESS, "key not created\n");
9416     RegCloseKey(hkey);
9417
9418     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9420
9421     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
9422     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9423
9424     ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n");
9425     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9426
9427     DeleteFileA("msitest\\mime.txt");
9428     delete_test_files();
9429 }
9430
9431 static void test_icon_table(void)
9432 {
9433     MSIHANDLE hdb = 0, record;
9434     LPCSTR query;
9435     UINT res;
9436     CHAR path[MAX_PATH], win9xpath[MAX_PATH];
9437     static const char prodcode[] = "{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}";
9438
9439     create_database(msifile, icon_base_tables, sizeof(icon_base_tables) / sizeof(msi_table));
9440
9441     res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb);
9442     ok(res == ERROR_SUCCESS, "failed to open db: %d\n", res);
9443
9444     query = "CREATE TABLE `Icon` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL  PRIMARY KEY `Name`)";
9445     res = run_query( hdb, 0, query );
9446     ok(res == ERROR_SUCCESS, "Can't create Icon table: %d\n", res);
9447
9448     create_file("icon.ico", 100);
9449     record = MsiCreateRecord(1);
9450     res = MsiRecordSetStream(record, 1, "icon.ico");
9451     ok(res == ERROR_SUCCESS, "Failed to add stream data to record: %d\n", res);
9452     DeleteFile("icon.ico");
9453
9454     query = "INSERT INTO `Icon` (`Name`, `Data`) VALUES ('testicon', ?)";
9455     res = run_query(hdb, record, query);
9456     ok(res == ERROR_SUCCESS, "Insert into Icon table failed: %d\n", res);
9457
9458     res = MsiCloseHandle(record);
9459     ok(res == ERROR_SUCCESS, "Failed to close record handle: %d\n", res);
9460     res = MsiDatabaseCommit(hdb);
9461     ok(res == ERROR_SUCCESS, "Failed to commit database: %d\n", res);
9462     res = MsiCloseHandle(hdb);
9463     ok(res == ERROR_SUCCESS, "Failed to close database: %d\n", res);
9464
9465     /* per-user */
9466     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
9467     ok(res == ERROR_SUCCESS, "Failed to do per-user install: %d\n", res);
9468
9469     lstrcpyA(path, APP_DATA_DIR);
9470     lstrcatA(path, "\\");
9471     lstrcatA(path, "Microsoft\\Installer\\");
9472     lstrcatA(path, prodcode);
9473     lstrcatA(path, "\\testicon");
9474     ok(file_exists(path), "Per-user icon file isn't where it's expected (%s)\n", path);
9475
9476     res = MsiInstallProductA(msifile, "REMOVE=ALL");
9477     ok(res == ERROR_SUCCESS, "Failed to uninstall per-user\n");
9478
9479     /* system-wide */
9480     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
9481     ok(res == ERROR_SUCCESS, "Failed to system-wide install: %d\n", res);
9482
9483     /* win9x with MSI 2.0 installs the icon to a different folder, same as above */
9484     lstrcpyA(win9xpath, APP_DATA_DIR);
9485     lstrcatA(path, "\\");
9486     lstrcatA(path, "Microsoft\\Installer\\");
9487     lstrcatA(path, prodcode);
9488     lstrcatA(path, "\\testicon");
9489
9490     lstrcpyA(path, WINDOWS_DIR);
9491     lstrcatA(path, "\\");
9492     lstrcatA(path, "Installer\\");
9493     lstrcatA(path, prodcode);
9494     lstrcatA(path, "\\testicon");
9495     ok(file_exists(path) || file_exists(win9xpath),
9496             "System-wide icon file isn't where it's expected (%s)\n", path);
9497
9498     res = MsiInstallProductA(msifile, "REMOVE=ALL");
9499     ok(res == ERROR_SUCCESS, "Failed to uninstall system-wide\n");
9500
9501     delete_pfmsitest_files();
9502
9503     DeleteFile(msifile);
9504 }
9505
9506 START_TEST(install)
9507 {
9508     DWORD len;
9509     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
9510     STATEMGRSTATUS status;
9511     BOOL ret = FALSE;
9512
9513     init_functionpointers();
9514
9515     on_win9x = check_win9x();
9516
9517     GetCurrentDirectoryA(MAX_PATH, prev_path);
9518     GetTempPath(MAX_PATH, temp_path);
9519     SetCurrentDirectoryA(temp_path);
9520
9521     lstrcpyA(CURR_DIR, temp_path);
9522     len = lstrlenA(CURR_DIR);
9523
9524     if(len && (CURR_DIR[len - 1] == '\\'))
9525         CURR_DIR[len - 1] = 0;
9526
9527     get_system_dirs();
9528     get_user_dirs();
9529
9530     /* Create a restore point ourselves so we circumvent the multitude of restore points
9531      * that would have been created by all the installation and removal tests.
9532      */
9533     if (pSRSetRestorePointA)
9534     {
9535         memset(&status, 0, sizeof(status));
9536         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
9537     }
9538
9539     /* Create only one log file and don't append. We have to pass something
9540      * for the log mode for this to work. The logfile needs to have an absolute
9541      * path otherwise we still end up with some extra logfiles as some tests
9542      * change the current directory.
9543      */
9544     lstrcpyA(log_file, temp_path);
9545     lstrcatA(log_file, "\\msitest.log");
9546     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
9547
9548     test_MsiInstallProduct();
9549     test_MsiSetComponentState();
9550     test_packagecoltypes();
9551     test_continuouscabs();
9552     test_caborder();
9553     test_mixedmedia();
9554     test_samesequence();
9555     test_uiLevelFlags();
9556     test_readonlyfile();
9557     test_readonlyfile_cab();
9558     test_setdirproperty();
9559     test_cabisextracted();
9560     test_concurrentinstall();
9561     test_setpropertyfolder();
9562     test_publish_registerproduct();
9563     test_publish_publishproduct();
9564     test_publish_publishfeatures();
9565     test_publish_registeruser();
9566     test_publish_processcomponents();
9567     test_publish();
9568     test_publishsourcelist();
9569     test_transformprop();
9570     test_currentworkingdir();
9571     test_admin();
9572     test_adminprops();
9573     test_removefiles();
9574     test_movefiles();
9575     test_missingcab();
9576     test_duplicatefiles();
9577     test_writeregistryvalues();
9578     test_sourcefolder();
9579     test_customaction51();
9580     test_installstate();
9581     test_sourcepath();
9582     test_MsiConfigureProductEx();
9583     test_missingcomponent();
9584     test_sourcedirprop();
9585     test_adminimage();
9586     test_propcase();
9587     test_int_widths();
9588     test_shortcut();
9589     test_envvar();
9590     test_lastusedsource();
9591     test_preselected();
9592     test_installed_prop();
9593     test_file_in_use();
9594     test_file_in_use_cab();
9595     test_MsiSetExternalUI();
9596     test_allusers_prop();
9597     test_feature_override();
9598     test_create_folder();
9599     test_remove_folder();
9600     test_start_services();
9601     test_delete_services();
9602     test_self_registration();
9603     test_register_font();
9604     test_validate_product_id();
9605     test_install_remove_odbc();
9606     test_register_typelib();
9607     test_create_remove_shortcut();
9608     test_publish_components();
9609     test_remove_duplicate_files();
9610     test_remove_registry_values();
9611     test_find_related_products();
9612     test_remove_ini_values();
9613     test_remove_env_strings();
9614     test_register_class_info();
9615     test_register_extension_info();
9616     test_register_mime_info();
9617     test_icon_table();
9618
9619     DeleteFileA(log_file);
9620
9621     if (pSRSetRestorePointA && ret)
9622     {
9623         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
9624         if (ret)
9625             remove_restore_point(status.llSequenceNumber);
9626     }
9627     FreeLibrary(hsrclient);
9628
9629     SetCurrentDirectoryA(prev_path);
9630 }