user32/tests: Restructure the DDE end-to-end tests to make it easier to add new cases.
[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", 0, &type, (LPBYTE)PROG_FILES_DIR, &size)) {
3250         RegCloseKey(hkey);
3251         return FALSE;
3252     }
3253
3254     size = MAX_PATH;
3255     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size)) {
3256         RegCloseKey(hkey);
3257         return FALSE;
3258     }
3259
3260     RegCloseKey(hkey);
3261
3262     if(GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH) != ERROR_SUCCESS)
3263         return FALSE;
3264
3265     return TRUE;
3266 }
3267
3268 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
3269 {
3270     HANDLE file;
3271     DWORD written;
3272
3273     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
3274     if (file == INVALID_HANDLE_VALUE)
3275         return;
3276
3277     WriteFile(file, data, strlen(data), &written, NULL);
3278
3279     if (size)
3280     {
3281         SetFilePointer(file, size, NULL, FILE_BEGIN);
3282         SetEndOfFile(file);
3283     }
3284
3285     CloseHandle(file);
3286 }
3287
3288 #define create_file(name, size) create_file_data(name, name, size)
3289
3290 static void create_test_files(void)
3291 {
3292     CreateDirectoryA("msitest", NULL);
3293     create_file("msitest\\one.txt", 100);
3294     CreateDirectoryA("msitest\\first", NULL);
3295     create_file("msitest\\first\\two.txt", 100);
3296     CreateDirectoryA("msitest\\second", NULL);
3297     create_file("msitest\\second\\three.txt", 100);
3298
3299     create_file("four.txt", 100);
3300     create_file("five.txt", 100);
3301     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
3302
3303     create_file("msitest\\filename", 100);
3304     create_file("msitest\\service.exe", 100);
3305
3306     DeleteFileA("four.txt");
3307     DeleteFileA("five.txt");
3308 }
3309
3310 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
3311 {
3312     CHAR path[MAX_PATH];
3313
3314     lstrcpyA(path, PROG_FILES_DIR);
3315     lstrcatA(path, "\\");
3316     lstrcatA(path, rel_path);
3317
3318     if (is_file)
3319         return DeleteFileA(path);
3320     else
3321         return RemoveDirectoryA(path);
3322 }
3323
3324 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
3325 {
3326     CHAR path[MAX_PATH];
3327
3328     lstrcpyA(path, COMMON_FILES_DIR);
3329     lstrcatA(path, "\\");
3330     lstrcatA(path, rel_path);
3331
3332     if (is_file)
3333         return DeleteFileA(path);
3334     else
3335         return RemoveDirectoryA(path);
3336 }
3337
3338 static void delete_test_files(void)
3339 {
3340     DeleteFileA("msitest.msi");
3341     DeleteFileA("msitest.cab");
3342     DeleteFileA("msitest\\second\\three.txt");
3343     DeleteFileA("msitest\\first\\two.txt");
3344     DeleteFileA("msitest\\one.txt");
3345     DeleteFileA("msitest\\service.exe");
3346     DeleteFileA("msitest\\filename");
3347     RemoveDirectoryA("msitest\\second");
3348     RemoveDirectoryA("msitest\\first");
3349     RemoveDirectoryA("msitest");
3350 }
3351
3352 static void write_file(const CHAR *filename, const char *data, int data_size)
3353 {
3354     DWORD size;
3355
3356     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
3357                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3358
3359     WriteFile(hf, data, data_size, &size, NULL);
3360     CloseHandle(hf);
3361 }
3362
3363 static void write_msi_summary_info(MSIHANDLE db, INT wordcount)
3364 {
3365     MSIHANDLE summary;
3366     UINT r;
3367
3368     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
3369     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3370
3371     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
3372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3373
3374     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3375                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
3376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3377
3378     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3379     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3380
3381     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
3382     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3383
3384     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3385     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3386
3387     /* write the summary changes back to the stream */
3388     r = MsiSummaryInfoPersist(summary);
3389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3390
3391     MsiCloseHandle(summary);
3392 }
3393
3394 #define create_database(name, tables, num_tables) \
3395     create_database_wordcount(name, tables, num_tables, 0);
3396
3397 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
3398                                       int num_tables, INT wordcount)
3399 {
3400     MSIHANDLE db;
3401     UINT r;
3402     int j;
3403
3404     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
3405     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3406
3407     /* import the tables into the database */
3408     for (j = 0; j < num_tables; j++)
3409     {
3410         const msi_table *table = &tables[j];
3411
3412         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
3413
3414         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
3415         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3416
3417         DeleteFileA(table->filename);
3418     }
3419
3420     write_msi_summary_info(db, wordcount);
3421
3422     r = MsiDatabaseCommit(db);
3423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3424
3425     MsiCloseHandle(db);
3426 }
3427
3428 static void check_service_is_installed(void)
3429 {
3430     SC_HANDLE scm, service;
3431     BOOL res;
3432
3433     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
3434     ok(scm != NULL, "Failed to open the SC Manager\n");
3435
3436     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
3437     ok(service != NULL, "Failed to open TestService\n");
3438
3439     res = DeleteService(service);
3440     ok(res, "Failed to delete TestService\n");
3441
3442     CloseServiceHandle(service);
3443     CloseServiceHandle(scm);
3444 }
3445
3446 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
3447 {
3448     RESTOREPOINTINFOA spec;
3449
3450     spec.dwEventType = event_type;
3451     spec.dwRestorePtType = APPLICATION_INSTALL;
3452     spec.llSequenceNumber = status->llSequenceNumber;
3453     lstrcpyA(spec.szDescription, "msitest restore point");
3454
3455     return pSRSetRestorePointA(&spec, status);
3456 }
3457
3458 static void remove_restore_point(DWORD seq_number)
3459 {
3460     DWORD res;
3461
3462     res = pSRRemoveRestorePoint(seq_number);
3463     if (res != ERROR_SUCCESS)
3464         trace("Failed to remove the restore point : %08x\n", res);
3465 }
3466
3467 static void test_MsiInstallProduct(void)
3468 {
3469     UINT r;
3470     CHAR path[MAX_PATH];
3471     LONG res;
3472     HKEY hkey;
3473     DWORD num, size, type;
3474
3475     if (on_win9x)
3476     {
3477         win_skip("Services are not implemented on Win9x and WinMe\n");
3478         return;
3479     }
3480
3481     /* szPackagePath is NULL */
3482     r = MsiInstallProductA(NULL, "INSTALL=ALL");
3483     ok(r == ERROR_INVALID_PARAMETER,
3484        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3485
3486     /* both szPackagePath and szCommandLine are NULL */
3487     r = MsiInstallProductA(NULL, NULL);
3488     ok(r == ERROR_INVALID_PARAMETER,
3489        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3490
3491     /* szPackagePath is empty */
3492     r = MsiInstallProductA("", "INSTALL=ALL");
3493     ok(r == ERROR_PATH_NOT_FOUND,
3494        "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
3495
3496     create_test_files();
3497     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3498
3499     /* install, don't publish */
3500     r = MsiInstallProductA(msifile, NULL);
3501     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3502
3503     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3504     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3505     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3506     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3507     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3508     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3509     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3510     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3511     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3512     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3513     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3514     ok(delete_pf("msitest", FALSE), "File not installed\n");
3515
3516     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3518
3519     size = MAX_PATH;
3520     type = REG_SZ;
3521     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
3522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3523     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
3524
3525     size = MAX_PATH;
3526     type = REG_SZ;
3527     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
3528     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3529
3530     size = sizeof(num);
3531     type = REG_DWORD;
3532     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
3533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3534     ok(num == 314, "Expected 314, got %d\n", num);
3535
3536     size = MAX_PATH;
3537     type = REG_SZ;
3538     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
3539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3540     ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
3541
3542     check_service_is_installed();
3543
3544     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3545
3546     /* not published, reinstall */
3547     r = MsiInstallProductA(msifile, NULL);
3548     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3549
3550     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3551     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3552     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3553     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3554     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3555     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3556     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3557     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3558     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3559     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3560     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3561     ok(delete_pf("msitest", FALSE), "File not installed\n");
3562
3563     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3564     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3565     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3566
3567     create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table));
3568
3569     /* not published, RemovePreviousVersions set */
3570     r = MsiInstallProductA(msifile, NULL);
3571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3572
3573     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3574     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3575     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3576     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3577     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3578     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3579     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3580     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3581     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3582     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3583     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3584     ok(delete_pf("msitest", FALSE), "File not installed\n");
3585
3586     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3588     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3589
3590     create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table));
3591
3592     /* not published, version number bumped */
3593     r = MsiInstallProductA(msifile, NULL);
3594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3595
3596     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3597     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3598     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3599     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3600     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3601     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3602     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3603     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3604     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3605     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3606     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3607     ok(delete_pf("msitest", FALSE), "File not installed\n");
3608
3609     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3611     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3612
3613     create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table));
3614
3615     /* not published, RemovePreviousVersions set and version number bumped */
3616     r = MsiInstallProductA(msifile, NULL);
3617     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3618
3619     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3620     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3621     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3622     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3623     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3624     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3625     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3626     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3627     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3628     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3629     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3630     ok(delete_pf("msitest", FALSE), "File not installed\n");
3631
3632     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3633     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3634     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
3635
3636     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3637
3638     /* install, publish product */
3639     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3640     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3641
3642     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3643     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3644     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3645     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3646     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3647     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3648     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3649     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3650     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3651     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3652     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3653     ok(delete_pf("msitest", FALSE), "File not installed\n");
3654
3655     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3656     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3657
3658     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
3659
3660     /* published, reinstall */
3661     r = MsiInstallProductA(msifile, NULL);
3662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3663
3664     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3665     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3666     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3667     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3668     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3669     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3670     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3671     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3672     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3673     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3674     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3675     ok(delete_pf("msitest", FALSE), "File not installed\n");
3676
3677     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3678     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3679
3680     create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table));
3681
3682     /* published product, RemovePreviousVersions set */
3683     r = MsiInstallProductA(msifile, NULL);
3684     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3685
3686     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3687     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3688     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3689     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3690     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3691     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3692     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3693     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3694     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3695     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3696     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3697     ok(delete_pf("msitest", FALSE), "File not installed\n");
3698
3699     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3700     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3701
3702     create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table));
3703
3704     /* published product, version number bumped */
3705     r = MsiInstallProductA(msifile, NULL);
3706     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3707
3708     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3709     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3710     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3711     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3712     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3713     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3714     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3715     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3716     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3717     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3718     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3719     ok(delete_pf("msitest", FALSE), "File not installed\n");
3720
3721     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3722     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3723
3724     create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table));
3725
3726     /* published product, RemovePreviousVersions set and version number bumped */
3727     r = MsiInstallProductA(msifile, NULL);
3728     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3729
3730     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
3731     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
3732     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
3733     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
3734     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
3735     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
3736     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
3737     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
3738     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
3739     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
3740     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
3741     ok(delete_pf("msitest", FALSE), "File not installed\n");
3742
3743     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
3744     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3745
3746     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3747     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3748
3749     delete_test_files();
3750 }
3751
3752 static void test_MsiSetComponentState(void)
3753 {
3754     INSTALLSTATE installed, action;
3755     MSIHANDLE package;
3756     char path[MAX_PATH];
3757     UINT r;
3758
3759     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3760
3761     CoInitialize(NULL);
3762
3763     lstrcpy(path, CURR_DIR);
3764     lstrcat(path, "\\");
3765     lstrcat(path, msifile);
3766
3767     r = MsiOpenPackage(path, &package);
3768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3769
3770     r = MsiDoAction(package, "CostInitialize");
3771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3772
3773     r = MsiDoAction(package, "FileCost");
3774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3775
3776     r = MsiDoAction(package, "CostFinalize");
3777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3778
3779     r = MsiGetComponentState(package, "dangler", &installed, &action);
3780     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3781     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
3782     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
3783
3784     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
3785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3786
3787     MsiCloseHandle(package);
3788     CoUninitialize();
3789
3790     DeleteFileA(msifile);
3791 }
3792
3793 static void test_packagecoltypes(void)
3794 {
3795     MSIHANDLE hdb, view, rec;
3796     char path[MAX_PATH];
3797     LPCSTR query;
3798     UINT r, count;
3799
3800     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
3801
3802     CoInitialize(NULL);
3803
3804     lstrcpy(path, CURR_DIR);
3805     lstrcat(path, "\\");
3806     lstrcat(path, msifile);
3807
3808     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
3809     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3810
3811     query = "SELECT * FROM `Media`";
3812     r = MsiDatabaseOpenView( hdb, query, &view );
3813     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
3814
3815     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
3816     count = MsiRecordGetFieldCount( rec );
3817     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3818     ok(count == 6, "Expected 6, got %d\n", count);
3819     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
3820     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
3821     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
3822     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
3823     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
3824     ok(check_record(rec, 6, "Source"), "wrong column label\n");
3825     MsiCloseHandle(rec);
3826
3827     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
3828     count = MsiRecordGetFieldCount( rec );
3829     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
3830     ok(count == 6, "Expected 6, got %d\n", count);
3831     ok(check_record(rec, 1, "i2"), "wrong column label\n");
3832     ok(check_record(rec, 2, "i4"), "wrong column label\n");
3833     ok(check_record(rec, 3, "L64"), "wrong column label\n");
3834     ok(check_record(rec, 4, "S255"), "wrong column label\n");
3835     ok(check_record(rec, 5, "S32"), "wrong column label\n");
3836     ok(check_record(rec, 6, "S72"), "wrong column label\n");
3837
3838     MsiCloseHandle(rec);
3839     MsiCloseHandle(view);
3840     MsiCloseHandle(hdb);
3841     CoUninitialize();
3842
3843     DeleteFile(msifile);
3844 }
3845
3846 static void create_cc_test_files(void)
3847 {
3848     CCAB cabParams;
3849     HFCI hfci;
3850     ERF erf;
3851     static CHAR cab_context[] = "test%d.cab";
3852     BOOL res;
3853
3854     create_file("maximus", 500);
3855     create_file("augustus", 50000);
3856     create_file("tiberius", 500);
3857     create_file("caesar", 500);
3858
3859     set_cab_parameters(&cabParams, "test1.cab", 40000);
3860
3861     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
3862                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
3863                       get_temp_file, &cabParams, cab_context);
3864     ok(hfci != NULL, "Failed to create an FCI context\n");
3865
3866     res = add_file(hfci, "maximus", tcompTYPE_NONE);
3867     ok(res, "Failed to add file maximus\n");
3868
3869     res = add_file(hfci, "augustus", tcompTYPE_NONE);
3870     ok(res, "Failed to add file augustus\n");
3871
3872     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
3873     ok(res, "Failed to add file tiberius\n");
3874
3875     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
3876     ok(res, "Failed to flush the cabinet\n");
3877
3878     res = FCIDestroy(hfci);
3879     ok(res, "Failed to destroy the cabinet\n");
3880
3881     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3882
3883     DeleteFile("maximus");
3884     DeleteFile("augustus");
3885     DeleteFile("tiberius");
3886     DeleteFile("caesar");
3887 }
3888
3889 static void delete_cab_files(void)
3890 {
3891     SHFILEOPSTRUCT shfl;
3892     CHAR path[MAX_PATH+10];
3893
3894     lstrcpyA(path, CURR_DIR);
3895     lstrcatA(path, "\\*.cab");
3896     path[strlen(path) + 1] = '\0';
3897
3898     shfl.hwnd = NULL;
3899     shfl.wFunc = FO_DELETE;
3900     shfl.pFrom = path;
3901     shfl.pTo = NULL;
3902     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
3903
3904     SHFileOperation(&shfl);
3905 }
3906
3907 static void test_continuouscabs(void)
3908 {
3909     UINT r;
3910
3911     create_cc_test_files();
3912     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3913
3914     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3915
3916     r = MsiInstallProductA(msifile, NULL);
3917     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
3918     {
3919         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3920         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3921         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3922         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3923         ok(delete_pf("msitest", FALSE), "File not installed\n");
3924     }
3925
3926     delete_cab_files();
3927     DeleteFile(msifile);
3928
3929     create_cc_test_files();
3930     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
3931
3932     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3933
3934     r = MsiInstallProductA(msifile, NULL);
3935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3936     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3937     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3938     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
3939     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3940     ok(delete_pf("msitest", FALSE), "File not installed\n");
3941
3942     delete_cab_files();
3943     DeleteFile(msifile);
3944 }
3945
3946 static void test_caborder(void)
3947 {
3948     UINT r;
3949
3950     create_file("imperator", 100);
3951     create_file("maximus", 500);
3952     create_file("augustus", 50000);
3953     create_file("caesar", 500);
3954
3955     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
3956
3957     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3958
3959     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3960     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3961     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3962
3963     r = MsiInstallProductA(msifile, NULL);
3964     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3965     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3966     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3967     todo_wine
3968     {
3969         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3970         ok(!delete_pf("msitest", FALSE), "File is installed\n");
3971     }
3972
3973     delete_cab_files();
3974
3975     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
3976     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
3977     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3978
3979     r = MsiInstallProductA(msifile, NULL);
3980     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3981     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
3982     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3983     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3984     ok(!delete_pf("msitest", FALSE), "File is installed\n");
3985
3986     delete_cab_files();
3987     DeleteFile(msifile);
3988
3989     create_cc_test_files();
3990     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
3991
3992     r = MsiInstallProductA(msifile, NULL);
3993     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
3994     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
3995     ok(!delete_pf("msitest", FALSE), "File is installed\n");
3996     todo_wine
3997     {
3998         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
3999         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
4000     }
4001
4002     delete_cab_files();
4003     DeleteFile(msifile);
4004
4005     create_cc_test_files();
4006     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
4007
4008     r = MsiInstallProductA(msifile, NULL);
4009     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
4010     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4011     todo_wine
4012     {
4013         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
4014         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
4015         ok(!delete_pf("msitest", FALSE), "File is installed\n");
4016     }
4017
4018     delete_cab_files();
4019     DeleteFile("imperator");
4020     DeleteFile("maximus");
4021     DeleteFile("augustus");
4022     DeleteFile("caesar");
4023     DeleteFile(msifile);
4024 }
4025
4026 static void test_mixedmedia(void)
4027 {
4028     UINT r;
4029
4030     CreateDirectoryA("msitest", NULL);
4031     create_file("msitest\\maximus", 500);
4032     create_file("msitest\\augustus", 500);
4033     create_file("caesar", 500);
4034
4035     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
4036
4037     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4038
4039     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
4040
4041     r = MsiInstallProductA(msifile, NULL);
4042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4043     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4044     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4045     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4046     ok(delete_pf("msitest", FALSE), "File not installed\n");
4047
4048     /* Delete the files in the temp (current) folder */
4049     DeleteFile("msitest\\maximus");
4050     DeleteFile("msitest\\augustus");
4051     RemoveDirectory("msitest");
4052     DeleteFile("caesar");
4053     DeleteFile("test1.cab");
4054     DeleteFile(msifile);
4055 }
4056
4057 static void test_samesequence(void)
4058 {
4059     UINT r;
4060
4061     create_cc_test_files();
4062     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
4063
4064     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4065
4066     r = MsiInstallProductA(msifile, NULL);
4067     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
4068     {
4069         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4070         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4071         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4072         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4073         ok(delete_pf("msitest", FALSE), "File not installed\n");
4074     }
4075
4076     delete_cab_files();
4077     DeleteFile(msifile);
4078 }
4079
4080 static void test_uiLevelFlags(void)
4081 {
4082     UINT r;
4083
4084     create_cc_test_files();
4085     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
4086
4087     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
4088
4089     r = MsiInstallProductA(msifile, NULL);
4090     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
4091     {
4092         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4093         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
4094         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4095         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4096         ok(delete_pf("msitest", FALSE), "File not installed\n");
4097     }
4098
4099     delete_cab_files();
4100     DeleteFile(msifile);
4101 }
4102
4103 static BOOL file_matches(LPSTR path)
4104 {
4105     CHAR buf[MAX_PATH];
4106     HANDLE file;
4107     DWORD size;
4108
4109     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4110                       NULL, OPEN_EXISTING, 0, NULL);
4111
4112     ZeroMemory(buf, MAX_PATH);
4113     ReadFile(file, buf, 15, &size, NULL);
4114     CloseHandle(file);
4115
4116     return !lstrcmp(buf, "msitest\\maximus");
4117 }
4118
4119 static void test_readonlyfile(void)
4120 {
4121     UINT r;
4122     DWORD size;
4123     HANDLE file;
4124     CHAR path[MAX_PATH];
4125
4126     CreateDirectoryA("msitest", NULL);
4127     create_file("msitest\\maximus", 500);
4128     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
4129
4130     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4131
4132     lstrcpy(path, PROG_FILES_DIR);
4133     lstrcat(path, "\\msitest");
4134     CreateDirectory(path, NULL);
4135
4136     lstrcat(path, "\\maximus");
4137     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4138                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
4139
4140     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
4141     CloseHandle(file);
4142
4143     r = MsiInstallProductA(msifile, NULL);
4144     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4145     ok(file_matches(path), "Expected file to be overwritten\n");
4146     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4147     ok(delete_pf("msitest", FALSE), "File not installed\n");
4148
4149     /* Delete the files in the temp (current) folder */
4150     DeleteFile("msitest\\maximus");
4151     RemoveDirectory("msitest");
4152     DeleteFile(msifile);
4153 }
4154
4155 static void test_readonlyfile_cab(void)
4156 {
4157     UINT r;
4158     DWORD size;
4159     HANDLE file;
4160     CHAR path[MAX_PATH];
4161     CHAR buf[16];
4162
4163     CreateDirectoryA("msitest", NULL);
4164     create_file("maximus", 500);
4165     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4166     DeleteFile("maximus");
4167
4168     create_database(msifile, rofc_tables, sizeof(rofc_tables) / sizeof(msi_table));
4169
4170     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4171
4172     lstrcpy(path, PROG_FILES_DIR);
4173     lstrcat(path, "\\msitest");
4174     CreateDirectory(path, NULL);
4175
4176     lstrcat(path, "\\maximus");
4177     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4178                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
4179
4180     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
4181     CloseHandle(file);
4182
4183     r = MsiInstallProductA(msifile, NULL);
4184     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4185
4186     memset( buf, 0, sizeof(buf) );
4187     if ((file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
4188                            NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
4189     {
4190         ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
4191         CloseHandle(file);
4192     }
4193     ok(!memcmp( buf, "maximus", sizeof("maximus")-1 ), "Expected file to be overwritten, got '%s'\n", buf);
4194     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4195     ok(delete_pf("msitest", FALSE), "File not installed\n");
4196
4197     /* Delete the files in the temp (current) folder */
4198     delete_cab_files();
4199     DeleteFile("msitest\\maximus");
4200     RemoveDirectory("msitest");
4201     DeleteFile(msifile);
4202 }
4203
4204 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
4205 {
4206     WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
4207     IStorage *stg;
4208     IStream *stm;
4209     HRESULT hr;
4210     HANDLE handle;
4211
4212     MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
4213     hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
4214     if (FAILED(hr))
4215         return FALSE;
4216
4217     MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
4218     hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4219     if (FAILED(hr))
4220     {
4221         IStorage_Release(stg);
4222         return FALSE;
4223     }
4224
4225     handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
4226     if (handle != INVALID_HANDLE_VALUE)
4227     {
4228         DWORD count;
4229         char buffer[1024];
4230         if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
4231             IStream_Write(stm, buffer, count, &count);
4232         CloseHandle(handle);
4233     }
4234
4235     IStream_Release(stm);
4236     IStorage_Release(stg);
4237
4238     return TRUE;
4239 }
4240
4241 static void test_lastusedsource(void)
4242 {
4243     static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4244
4245     UINT r;
4246     char value[MAX_PATH], path[MAX_PATH];
4247     DWORD size;
4248
4249     if (!pMsiSourceListGetInfoA)
4250     {
4251         win_skip("MsiSourceListGetInfoA is not available\n");
4252         return;
4253     }
4254
4255     CreateDirectoryA("msitest", NULL);
4256     create_file("maximus", 500);
4257     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4258     DeleteFile("maximus");
4259
4260     create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
4261     create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
4262     create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
4263
4264     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4265
4266     /* no cabinet file */
4267
4268     size = MAX_PATH;
4269     lstrcpyA(value, "aaa");
4270     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4271                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4272     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4273     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4274
4275     r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
4276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4277
4278     lstrcpyA(path, CURR_DIR);
4279     lstrcatA(path, "\\");
4280
4281     size = MAX_PATH;
4282     lstrcpyA(value, "aaa");
4283     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4284                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4286     todo_wine
4287     {
4288     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4289     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4290     }
4291
4292     r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
4293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4294
4295     /* separate cabinet file */
4296
4297     size = MAX_PATH;
4298     lstrcpyA(value, "aaa");
4299     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4300                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4301     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4302     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4303
4304     r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
4305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4306
4307     lstrcpyA(path, CURR_DIR);
4308     lstrcatA(path, "\\");
4309
4310     size = MAX_PATH;
4311     lstrcpyA(value, "aaa");
4312     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4313                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4315     todo_wine
4316     {
4317     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4318     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4319     }
4320
4321     r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
4322     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4323
4324     size = MAX_PATH;
4325     lstrcpyA(value, "aaa");
4326     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4327                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4328     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4329     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4330
4331     /* embedded cabinet stream */
4332
4333     add_cabinet_storage("msifile2.msi", "test1.cab");
4334
4335     r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
4336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4337
4338     size = MAX_PATH;
4339     lstrcpyA(value, "aaa");
4340     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4341                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4343     todo_wine
4344     {
4345     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4346     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4347     }
4348
4349     r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
4350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4351
4352     size = MAX_PATH;
4353     lstrcpyA(value, "aaa");
4354     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4355                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4356     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
4357     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4358
4359     /* Delete the files in the temp (current) folder */
4360     delete_cab_files();
4361     DeleteFile("msitest\\maximus");
4362     RemoveDirectory("msitest");
4363     DeleteFile("msifile0.msi");
4364     DeleteFile("msifile1.msi");
4365     DeleteFile("msifile2.msi");
4366 }
4367
4368 static void test_setdirproperty(void)
4369 {
4370     UINT r;
4371
4372     CreateDirectoryA("msitest", NULL);
4373     create_file("msitest\\maximus", 500);
4374     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
4375
4376     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4377
4378     r = MsiInstallProductA(msifile, NULL);
4379     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4380     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
4381     ok(delete_cf("msitest", FALSE), "File not installed\n");
4382
4383     /* Delete the files in the temp (current) folder */
4384     DeleteFile(msifile);
4385     DeleteFile("msitest\\maximus");
4386     RemoveDirectory("msitest");
4387 }
4388
4389 static void test_cabisextracted(void)
4390 {
4391     UINT r;
4392
4393     CreateDirectoryA("msitest", NULL);
4394     create_file("msitest\\gaius", 500);
4395     create_file("maximus", 500);
4396     create_file("augustus", 500);
4397     create_file("caesar", 500);
4398
4399     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4400     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
4401     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
4402
4403     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
4404
4405     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4406
4407     r = MsiInstallProductA(msifile, NULL);
4408     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4409     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4410     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4411     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4412     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
4413     ok(delete_pf("msitest", FALSE), "File not installed\n");
4414
4415     /* Delete the files in the temp (current) folder */
4416     delete_cab_files();
4417     DeleteFile(msifile);
4418     DeleteFile("maximus");
4419     DeleteFile("augustus");
4420     DeleteFile("caesar");
4421     DeleteFile("msitest\\gaius");
4422     RemoveDirectory("msitest");
4423 }
4424
4425 static void test_concurrentinstall(void)
4426 {
4427     UINT r;
4428     CHAR path[MAX_PATH];
4429
4430     CreateDirectoryA("msitest", NULL);
4431     CreateDirectoryA("msitest\\msitest", NULL);
4432     create_file("msitest\\maximus", 500);
4433     create_file("msitest\\msitest\\augustus", 500);
4434
4435     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
4436
4437     lstrcpyA(path, CURR_DIR);
4438     lstrcatA(path, "\\msitest\\concurrent.msi");
4439     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
4440
4441     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4442
4443     r = MsiInstallProductA(msifile, NULL);
4444     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4445     if (!delete_pf("msitest\\augustus", TRUE))
4446         trace("concurrent installs not supported\n");
4447     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4448     ok(delete_pf("msitest", FALSE), "File not installed\n");
4449
4450     DeleteFile(path);
4451
4452     r = MsiInstallProductA(msifile, NULL);
4453     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4454     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4455     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4456     ok(delete_pf("msitest", FALSE), "File not installed\n");
4457
4458     DeleteFile(msifile);
4459     DeleteFile("msitest\\msitest\\augustus");
4460     DeleteFile("msitest\\maximus");
4461     RemoveDirectory("msitest\\msitest");
4462     RemoveDirectory("msitest");
4463 }
4464
4465 static void test_setpropertyfolder(void)
4466 {
4467     UINT r;
4468     CHAR path[MAX_PATH];
4469     DWORD attr;
4470
4471     lstrcpyA(path, PROG_FILES_DIR);
4472     lstrcatA(path, "\\msitest\\added");
4473
4474     CreateDirectoryA("msitest", NULL);
4475     create_file("msitest\\maximus", 500);
4476
4477     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
4478
4479     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4480
4481     r = MsiInstallProductA(msifile, NULL);
4482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4483     attr = GetFileAttributesA(path);
4484     if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
4485     {
4486         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
4487         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
4488         ok(delete_pf("msitest", FALSE), "File not installed\n");
4489     }
4490     else
4491     {
4492         trace("changing folder property not supported\n");
4493         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4494         ok(delete_pf("msitest", FALSE), "File not installed\n");
4495     }
4496
4497     /* Delete the files in the temp (current) folder */
4498     DeleteFile(msifile);
4499     DeleteFile("msitest\\maximus");
4500     RemoveDirectory("msitest");
4501 }
4502
4503 static BOOL file_exists(LPCSTR file)
4504 {
4505     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
4506 }
4507
4508 static BOOL pf_exists(LPCSTR file)
4509 {
4510     CHAR path[MAX_PATH];
4511
4512     lstrcpyA(path, PROG_FILES_DIR);
4513     lstrcatA(path, "\\");
4514     lstrcatA(path, file);
4515
4516     return file_exists(path);
4517 }
4518
4519 static void delete_pfmsitest_files(void)
4520 {
4521     SHFILEOPSTRUCT shfl;
4522     CHAR path[MAX_PATH+11];
4523
4524     lstrcpyA(path, PROG_FILES_DIR);
4525     lstrcatA(path, "\\msitest\\*");
4526     path[strlen(path) + 1] = '\0';
4527
4528     shfl.hwnd = NULL;
4529     shfl.wFunc = FO_DELETE;
4530     shfl.pFrom = path;
4531     shfl.pTo = NULL;
4532     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
4533
4534     SHFileOperation(&shfl);
4535
4536     lstrcpyA(path, PROG_FILES_DIR);
4537     lstrcatA(path, "\\msitest");
4538     RemoveDirectoryA(path);
4539 }
4540
4541 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
4542 {
4543     char val[MAX_PATH];
4544     DWORD size, type;
4545     LONG res;
4546
4547     size = MAX_PATH;
4548     val[0] = '\0';
4549     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
4550
4551     if (res != ERROR_SUCCESS ||
4552         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
4553     {
4554         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4555         return;
4556     }
4557
4558     if (!expected)
4559         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
4560     else
4561     {
4562         if (bcase)
4563             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
4564         else
4565             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
4566     }
4567 }
4568
4569 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
4570 {
4571     DWORD val, size, type;
4572     LONG res;
4573
4574     size = sizeof(DWORD);
4575     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4576
4577     if (res != ERROR_SUCCESS || type != REG_DWORD)
4578     {
4579         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4580         return;
4581     }
4582
4583     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
4584 }
4585
4586 static void check_reg_dword2(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD line)
4587 {
4588     DWORD val, size, type;
4589     LONG res;
4590
4591     size = sizeof(DWORD);
4592     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4593
4594     if (res != ERROR_SUCCESS || type != REG_DWORD)
4595     {
4596         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4597         return;
4598     }
4599
4600     ok_(__FILE__, line)(val == expected1 || val == expected2, "Expected %d or %d, got %d\n", expected1, expected2, val);
4601 }
4602
4603 static void check_reg_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line)
4604 {
4605     DWORD val, size, type;
4606     LONG res;
4607
4608     size = sizeof(DWORD);
4609     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
4610
4611     if (res != ERROR_SUCCESS || type != REG_DWORD)
4612     {
4613         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
4614         return;
4615     }
4616
4617     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3,
4618                         "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val);
4619 }
4620
4621 #define CHECK_REG_STR(prodkey, name, expected) \
4622     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
4623
4624 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
4625     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
4626     RegDeleteValueA(prodkey, name);
4627
4628 #define CHECK_REG_ISTR(prodkey, name, expected) \
4629     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
4630
4631 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
4632     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
4633     RegDeleteValueA(prodkey, name);
4634
4635 #define CHECK_REG_DWORD(prodkey, name, expected) \
4636     check_reg_dword(prodkey, name, expected, __LINE__);
4637
4638 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
4639     check_reg_dword(prodkey, name, expected, __LINE__); \
4640     RegDeleteValueA(prodkey, name);
4641
4642 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
4643     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
4644
4645 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
4646     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
4647     RegDeleteValueA(prodkey, name);
4648
4649 #define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4650     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__);
4651
4652 #define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
4653     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \
4654     RegDeleteValueA(prodkey, name);
4655
4656 static void get_date_str(LPSTR date)
4657 {
4658     SYSTEMTIME systime;
4659
4660     static const char date_fmt[] = "%d%02d%02d";
4661     GetLocalTime(&systime);
4662     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
4663 }
4664
4665 static void test_publish_registerproduct(void)
4666 {
4667     UINT r;
4668     LONG res;
4669     HKEY hkey;
4670     HKEY props, usage;
4671     LPSTR usersid;
4672     char date[MAX_PATH];
4673     char temp[MAX_PATH];
4674     char keypath[MAX_PATH];
4675
4676     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4677                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4678     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4679                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4680     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
4681                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4682     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4683                                     "\\51AAE0C44620A5E4788506E91F249BD2";
4684
4685     if (!get_user_sid(&usersid))
4686         return;
4687
4688     get_date_str(date);
4689     GetTempPath(MAX_PATH, temp);
4690
4691     CreateDirectoryA("msitest", NULL);
4692     create_file("msitest\\maximus", 500);
4693
4694     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4695
4696     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4697
4698     /* RegisterProduct */
4699     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4700     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4701     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4702     ok(delete_pf("msitest", FALSE), "File not installed\n");
4703
4704     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
4705     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4706
4707     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4709
4710     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4711     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4712     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4713     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4714     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4715     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4716     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4717     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4718     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4719     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4720     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4721     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4722     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4723     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4724     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4725     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4726     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4727     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4728     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4729     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4730     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4731     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4732     todo_wine
4733     {
4734         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4735     }
4736
4737     RegDeleteKeyA(hkey, "");
4738     RegCloseKey(hkey);
4739
4740     sprintf(keypath, userdata, usersid);
4741     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4743
4744     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4746
4747     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4748     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4749     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4750     CHECK_DEL_REG_STR(props, "InstallDate", date);
4751     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4752     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4753     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4754     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4755     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4756     CHECK_DEL_REG_STR(props, "Comments", NULL);
4757     CHECK_DEL_REG_STR(props, "Contact", NULL);
4758     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4759     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4760     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4761     CHECK_DEL_REG_STR(props, "Readme", NULL);
4762     CHECK_DEL_REG_STR(props, "Size", NULL);
4763     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4764     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4765     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4766     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4767     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4768     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4769     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4770     todo_wine
4771     {
4772         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4773     }
4774
4775     RegDeleteKeyA(props, "");
4776     RegCloseKey(props);
4777
4778     res = RegOpenKeyA(hkey, "Usage", &usage);
4779     todo_wine
4780     {
4781         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4782     }
4783
4784     RegDeleteKeyA(usage, "");
4785     RegCloseKey(usage);
4786     RegDeleteKeyA(hkey, "");
4787     RegCloseKey(hkey);
4788
4789     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4790     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4791
4792     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4793
4794     RegDeleteKeyA(hkey, "");
4795     RegCloseKey(hkey);
4796
4797     /* RegisterProduct, machine */
4798     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
4799     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4800     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4801     ok(delete_pf("msitest", FALSE), "File not installed\n");
4802
4803     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
4804     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4805
4806     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
4807     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4808
4809     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
4810     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
4811     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
4812     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
4813     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4814     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
4815     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4816     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
4817     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
4818     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
4819     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
4820     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
4821     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
4822     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
4823     CHECK_DEL_REG_STR(hkey, "Size", NULL);
4824     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
4825     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
4826     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4827     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4828     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
4829     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
4830     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
4831     todo_wine
4832     {
4833         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
4834     }
4835
4836     RegDeleteKeyA(hkey, "");
4837     RegCloseKey(hkey);
4838
4839     sprintf(keypath, userdata, "S-1-5-18");
4840     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4842
4843     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4845
4846     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
4847     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
4848     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
4849     CHECK_DEL_REG_STR(props, "InstallDate", date);
4850     CHECK_DEL_REG_STR(props, "InstallSource", temp);
4851     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4852     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
4853     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4854     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
4855     CHECK_DEL_REG_STR(props, "Comments", NULL);
4856     CHECK_DEL_REG_STR(props, "Contact", NULL);
4857     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
4858     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
4859     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
4860     CHECK_DEL_REG_STR(props, "Readme", NULL);
4861     CHECK_DEL_REG_STR(props, "Size", NULL);
4862     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
4863     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
4864     CHECK_DEL_REG_DWORD(props, "Language", 1033);
4865     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
4866     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
4867     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
4868     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
4869     todo_wine
4870     {
4871         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
4872     }
4873
4874     RegDeleteKeyA(props, "");
4875     RegCloseKey(props);
4876
4877     res = RegOpenKeyA(hkey, "Usage", &usage);
4878     todo_wine
4879     {
4880         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4881     }
4882
4883     RegDeleteKeyA(usage, "");
4884     RegCloseKey(usage);
4885     RegDeleteKeyA(hkey, "");
4886     RegCloseKey(hkey);
4887
4888     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
4889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4890
4891     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
4892
4893     RegDeleteKeyA(hkey, "");
4894     RegCloseKey(hkey);
4895
4896     DeleteFile(msifile);
4897     DeleteFile("msitest\\maximus");
4898     RemoveDirectory("msitest");
4899     HeapFree(GetProcessHeap(), 0, usersid);
4900 }
4901
4902 static void test_publish_publishproduct(void)
4903 {
4904     UINT r;
4905     LONG res;
4906     LPSTR usersid;
4907     HKEY sourcelist, net, props;
4908     HKEY hkey, patches, media;
4909     CHAR keypath[MAX_PATH];
4910     CHAR temp[MAX_PATH];
4911     CHAR path[MAX_PATH];
4912     BOOL old_installer = FALSE;
4913
4914     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4915                                    "\\Installer\\UserData\\%s\\Products"
4916                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4917     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
4918                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4919     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
4920                                      "\\51AAE0C44620A5E4788506E91F249BD2";
4921     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
4922                                   "\\Installer\\Products"
4923                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4924     static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
4925     static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
4926
4927     if (!get_user_sid(&usersid))
4928         return;
4929
4930     GetTempPath(MAX_PATH, temp);
4931
4932     CreateDirectoryA("msitest", NULL);
4933     create_file("msitest\\maximus", 500);
4934
4935     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4936
4937     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4938
4939     /* PublishProduct, current user */
4940     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4942     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4943     ok(delete_pf("msitest", FALSE), "File not installed\n");
4944
4945     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
4946     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4947
4948     sprintf(keypath, prodpath, usersid);
4949     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
4950     if (res == ERROR_FILE_NOT_FOUND)
4951     {
4952         res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4953         if (res == ERROR_SUCCESS)
4954         {
4955             win_skip("Windows Installer < 3.0 detected\n");
4956             RegCloseKey(hkey);
4957             old_installer = TRUE;
4958             goto currentuser;
4959         }
4960         else
4961         {
4962             win_skip("Install failed, no need to continue\n");
4963             return;
4964         }
4965     }
4966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4967
4968     res = RegOpenKeyA(hkey, "InstallProperties", &props);
4969     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4970
4971     res = RegOpenKeyA(hkey, "Patches", &patches);
4972     todo_wine
4973     {
4974         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4975
4976         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
4977     }
4978
4979     RegDeleteKeyA(patches, "");
4980     RegCloseKey(patches);
4981     RegDeleteKeyA(hkey, "");
4982     RegCloseKey(hkey);
4983
4984 currentuser:
4985     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
4986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4987
4988     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
4989     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
4990     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
4991     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
4992     if (!old_installer)
4993         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
4994     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
4995     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
4996     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
4997     CHECK_DEL_REG_STR(hkey, "Clients", ":");
4998
4999     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
5000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5001
5002     lstrcpyA(path, "n;1;");
5003     lstrcatA(path, temp);
5004     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
5005     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
5006
5007     res = RegOpenKeyA(sourcelist, "Net", &net);
5008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5009
5010     CHECK_DEL_REG_STR(net, "1", temp);
5011
5012     RegDeleteKeyA(net, "");
5013     RegCloseKey(net);
5014
5015     res = RegOpenKeyA(sourcelist, "Media", &media);
5016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5017
5018     CHECK_DEL_REG_STR(media, "1", "DISK1;");
5019
5020     RegDeleteKeyA(media, "");
5021     RegCloseKey(media);
5022     RegDeleteKeyA(sourcelist, "");
5023     RegCloseKey(sourcelist);
5024     RegDeleteKeyA(hkey, "");
5025     RegCloseKey(hkey);
5026
5027     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
5028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5029
5030     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
5031
5032     RegDeleteKeyA(hkey, "");
5033     RegCloseKey(hkey);
5034
5035     /* PublishProduct, machine */
5036     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
5037     if (old_installer)
5038         goto machprod;
5039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5040     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5041     ok(delete_pf("msitest", FALSE), "File not installed\n");
5042
5043     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
5044     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5045
5046     sprintf(keypath, prodpath, "S-1-5-18");
5047     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
5048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5049
5050     res = RegOpenKeyA(hkey, "InstallProperties", &props);
5051     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5052
5053     res = RegOpenKeyA(hkey, "Patches", &patches);
5054     todo_wine
5055     {
5056         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5057
5058         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
5059     }
5060
5061     RegDeleteKeyA(patches, "");
5062     RegCloseKey(patches);
5063     RegDeleteKeyA(hkey, "");
5064     RegCloseKey(hkey);
5065
5066 machprod:
5067     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
5068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5069
5070     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
5071     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
5072     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
5073     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
5074     if (!old_installer)
5075         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
5076     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
5077     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
5078     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
5079     CHECK_DEL_REG_STR(hkey, "Clients", ":");
5080
5081     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
5082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5083
5084     lstrcpyA(path, "n;1;");
5085     lstrcatA(path, temp);
5086     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
5087     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
5088
5089     res = RegOpenKeyA(sourcelist, "Net", &net);
5090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5091
5092     CHECK_DEL_REG_STR(net, "1", temp);
5093
5094     RegDeleteKeyA(net, "");
5095     RegCloseKey(net);
5096
5097     res = RegOpenKeyA(sourcelist, "Media", &media);
5098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5099
5100     CHECK_DEL_REG_STR(media, "1", "DISK1;");
5101
5102     RegDeleteKeyA(media, "");
5103     RegCloseKey(media);
5104     RegDeleteKeyA(sourcelist, "");
5105     RegCloseKey(sourcelist);
5106     RegDeleteKeyA(hkey, "");
5107     RegCloseKey(hkey);
5108
5109     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
5110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5111
5112     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
5113
5114     RegDeleteKeyA(hkey, "");
5115     RegCloseKey(hkey);
5116
5117     DeleteFile(msifile);
5118     DeleteFile("msitest\\maximus");
5119     RemoveDirectory("msitest");
5120     HeapFree(GetProcessHeap(), 0, usersid);
5121 }
5122
5123 static void test_publish_publishfeatures(void)
5124 {
5125     UINT r;
5126     LONG res;
5127     HKEY hkey;
5128     LPSTR usersid;
5129     CHAR keypath[MAX_PATH];
5130
5131     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
5132                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
5133     static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
5134                                  "\\Installer\\UserData\\%s\\Products"
5135                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
5136     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
5137                                   "\\Installer\\Features";
5138     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
5139                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
5140
5141     if (!get_user_sid(&usersid))
5142         return;
5143
5144     CreateDirectoryA("msitest", NULL);
5145     create_file("msitest\\maximus", 500);
5146
5147     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5148
5149     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5150
5151     /* PublishFeatures, current user */
5152     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
5153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5154     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5155     ok(delete_pf("msitest", FALSE), "File not installed\n");
5156
5157     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
5158     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5159
5160     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
5161     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5162
5163     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
5164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5165
5166     CHECK_REG_STR(hkey, "feature", "");
5167     CHECK_REG_STR(hkey, "montecristo", "");
5168
5169     RegDeleteValueA(hkey, "feature");
5170     RegDeleteValueA(hkey, "montecristo");
5171     RegDeleteKeyA(hkey, "");
5172     RegCloseKey(hkey);
5173
5174     sprintf(keypath, udpath, usersid);
5175     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
5176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5177
5178     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
5179     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
5180
5181     RegDeleteValueA(hkey, "feature");
5182     RegDeleteValueA(hkey, "montecristo");
5183     RegDeleteKeyA(hkey, "");
5184     RegCloseKey(hkey);
5185
5186     /* PublishFeatures, machine */
5187     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
5188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5189     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5190     ok(delete_pf("msitest", FALSE), "File not installed\n");
5191
5192     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
5193     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5194
5195     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
5196     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5197
5198     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
5199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5200
5201     CHECK_REG_STR(hkey, "feature", "");
5202     CHECK_REG_STR(hkey, "montecristo", "");
5203
5204     RegDeleteValueA(hkey, "feature");
5205     RegDeleteValueA(hkey, "montecristo");
5206     RegDeleteKeyA(hkey, "");
5207     RegCloseKey(hkey);
5208
5209     sprintf(keypath, udpath, "S-1-5-18");
5210     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
5211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5212
5213     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
5214     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
5215
5216     RegDeleteValueA(hkey, "feature");
5217     RegDeleteValueA(hkey, "montecristo");
5218     RegDeleteKeyA(hkey, "");
5219     RegCloseKey(hkey);
5220
5221     DeleteFile(msifile);
5222     DeleteFile("msitest\\maximus");
5223     RemoveDirectory("msitest");
5224     HeapFree(GetProcessHeap(), 0, usersid);
5225 }
5226
5227 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
5228 {
5229     DWORD len = 0;
5230     LPSTR val;
5231     LONG r;
5232
5233     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
5234     if (r != ERROR_SUCCESS)
5235         return NULL;
5236
5237     len += sizeof (WCHAR);
5238     val = HeapAlloc(GetProcessHeap(), 0, len);
5239     if (!val) return NULL;
5240     val[0] = 0;
5241     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
5242     return val;
5243 }
5244
5245 static void get_owner_company(LPSTR *owner, LPSTR *company)
5246 {
5247     LONG res;
5248     HKEY hkey;
5249
5250     *owner = *company = NULL;
5251
5252     res = RegOpenKeyA(HKEY_CURRENT_USER,
5253                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
5254     if (res == ERROR_SUCCESS)
5255     {
5256         *owner = reg_get_val_str(hkey, "DefName");
5257         *company = reg_get_val_str(hkey, "DefCompany");
5258         RegCloseKey(hkey);
5259     }
5260
5261     if (!*owner || !*company)
5262     {
5263         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
5264                           "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
5265         if (res == ERROR_SUCCESS)
5266         {
5267             *owner = reg_get_val_str(hkey, "RegisteredOwner");
5268             *company = reg_get_val_str(hkey, "RegisteredOrganization");
5269             RegCloseKey(hkey);
5270         }
5271     }
5272
5273     if (!*owner || !*company)
5274     {
5275         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
5276                           "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
5277         if (res == ERROR_SUCCESS)
5278         {
5279             *owner = reg_get_val_str(hkey, "RegisteredOwner");
5280             *company = reg_get_val_str(hkey, "RegisteredOrganization");
5281             RegCloseKey(hkey);
5282         }
5283     }
5284 }
5285
5286 static void test_publish_registeruser(void)
5287 {
5288     UINT r;
5289     LONG res;
5290     HKEY props;
5291     LPSTR usersid;
5292     LPSTR owner, company;
5293     CHAR keypath[MAX_PATH];
5294
5295     static const CHAR keyfmt[] =
5296         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
5297         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
5298
5299     if (!get_user_sid(&usersid))
5300         return;
5301
5302     get_owner_company(&owner, &company);
5303
5304     CreateDirectoryA("msitest", NULL);
5305     create_file("msitest\\maximus", 500);
5306
5307     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5308
5309     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5310
5311     /* RegisterUser, per-user */
5312     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
5313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5314     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5315     ok(delete_pf("msitest", FALSE), "File not installed\n");
5316
5317     sprintf(keypath, keyfmt, usersid);
5318
5319     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5320     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5321
5322     CHECK_REG_STR(props, "ProductID", "none");
5323     CHECK_REG_STR(props, "RegCompany", company);
5324     CHECK_REG_STR(props, "RegOwner", owner);
5325
5326     RegDeleteValueA(props, "ProductID");
5327     RegDeleteValueA(props, "RegCompany");
5328     RegDeleteValueA(props, "RegOwner");
5329     RegDeleteKeyA(props, "");
5330     RegCloseKey(props);
5331
5332     /* RegisterUser, machine */
5333     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
5334     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5335     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5336     ok(delete_pf("msitest", FALSE), "File not installed\n");
5337
5338     sprintf(keypath, keyfmt, "S-1-5-18");
5339
5340     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
5341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5342
5343     CHECK_REG_STR(props, "ProductID", "none");
5344     CHECK_REG_STR(props, "RegCompany", company);
5345     CHECK_REG_STR(props, "RegOwner", owner);
5346
5347     RegDeleteValueA(props, "ProductID");
5348     RegDeleteValueA(props, "RegCompany");
5349     RegDeleteValueA(props, "RegOwner");
5350     RegDeleteKeyA(props, "");
5351     RegCloseKey(props);
5352
5353     HeapFree(GetProcessHeap(), 0, company);
5354     HeapFree(GetProcessHeap(), 0, owner);
5355
5356     DeleteFile(msifile);
5357     DeleteFile("msitest\\maximus");
5358     RemoveDirectory("msitest");
5359     LocalFree(usersid);
5360 }
5361
5362 static void test_publish_processcomponents(void)
5363 {
5364     UINT r;
5365     LONG res;
5366     DWORD size;
5367     HKEY comp, hkey;
5368     LPSTR usersid;
5369     CHAR val[MAX_PATH];
5370     CHAR keypath[MAX_PATH];
5371     CHAR program_files_maximus[MAX_PATH];
5372
5373     static const CHAR keyfmt[] =
5374         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
5375         "UserData\\%s\\Components\\%s";
5376     static const CHAR compkey[] =
5377         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
5378
5379     if (!get_user_sid(&usersid))
5380         return;
5381
5382     CreateDirectoryA("msitest", NULL);
5383     create_file("msitest\\maximus", 500);
5384
5385     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
5386
5387     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5388
5389     /* ProcessComponents, per-user */
5390     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
5391     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5392     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5393     ok(delete_pf("msitest", FALSE), "File not installed\n");
5394
5395     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
5396
5397     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5398     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5399
5400     size = MAX_PATH;
5401     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5402                            NULL, NULL, (LPBYTE)val, &size);
5403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5404
5405     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
5406     lstrcatA(program_files_maximus,"\\msitest\\maximus");
5407
5408     ok(!lstrcmpiA(val, program_files_maximus),
5409        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5410
5411     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5412     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5413
5414     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5415     RegDeleteKeyA(comp, "");
5416     RegCloseKey(comp);
5417
5418     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
5419
5420     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5422
5423     size = MAX_PATH;
5424     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5425                            NULL, NULL, (LPBYTE)val, &size);
5426     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5427     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5428        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5429
5430     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5431     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5432
5433     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5434     RegDeleteKeyA(comp, "");
5435     RegCloseKey(comp);
5436
5437     /* ProcessComponents, machine */
5438     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
5439     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5440     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5441     ok(delete_pf("msitest", FALSE), "File not installed\n");
5442
5443     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
5444
5445     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5447
5448     size = MAX_PATH;
5449     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5450                            NULL, NULL, (LPBYTE)val, &size);
5451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5452     ok(!lstrcmpiA(val, program_files_maximus),
5453        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
5454
5455     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5456     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5457
5458     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5459     RegDeleteKeyA(comp, "");
5460     RegCloseKey(comp);
5461
5462     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
5463
5464     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
5465     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5466
5467     size = MAX_PATH;
5468     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
5469                            NULL, NULL, (LPBYTE)val, &size);
5470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5471     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
5472        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
5473
5474     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
5475     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5476
5477     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
5478     RegDeleteKeyA(comp, "");
5479     RegCloseKey(comp);
5480
5481     DeleteFile(msifile);
5482     DeleteFile("msitest\\maximus");
5483     RemoveDirectory("msitest");
5484     LocalFree(usersid);
5485 }
5486
5487 static void test_publish(void)
5488 {
5489     UINT r;
5490     LONG res;
5491     HKEY uninstall, prodkey;
5492     INSTALLSTATE state;
5493     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5494     char date[MAX_PATH];
5495     char temp[MAX_PATH];
5496
5497     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
5498
5499     if (!pMsiQueryComponentStateA)
5500     {
5501         win_skip("MsiQueryComponentStateA is not available\n");
5502         return;
5503     }
5504
5505     get_date_str(date);
5506     GetTempPath(MAX_PATH, temp);
5507
5508     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
5509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5510
5511     CreateDirectoryA("msitest", NULL);
5512     create_file("msitest\\maximus", 500);
5513
5514     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5515
5516     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5517
5518     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5519     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5520
5521     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5522     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5523
5524     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5525     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5526
5527     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5528                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5529     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5530     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5531
5532     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5533     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5534
5535     /* nothing published */
5536     r = MsiInstallProductA(msifile, NULL);
5537     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5538     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5539     ok(pf_exists("msitest"), "File not installed\n");
5540
5541     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5542     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5543
5544     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5545     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5546
5547     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5548     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5549
5550     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5551                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5552     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5553     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5554
5555     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5556     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5557
5558     /* PublishProduct and RegisterProduct */
5559     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
5560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5561     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5562     ok(pf_exists("msitest"), "File not installed\n");
5563
5564     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5565     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5566
5567     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5568     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5569
5570     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5571     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5572
5573     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5574                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5575     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
5576     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5577
5578     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5580
5581     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5582     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5583     CHECK_REG_STR(prodkey, "InstallDate", date);
5584     CHECK_REG_STR(prodkey, "InstallSource", temp);
5585     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5586     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5587     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5588     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5589     CHECK_REG_STR(prodkey, "Comments", NULL);
5590     CHECK_REG_STR(prodkey, "Contact", NULL);
5591     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5592     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5593     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5594     CHECK_REG_STR(prodkey, "Readme", NULL);
5595     CHECK_REG_STR(prodkey, "Size", NULL);
5596     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5597     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5598     CHECK_REG_DWORD(prodkey, "Language", 1033);
5599     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5600     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5601     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5602     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5603     todo_wine
5604     {
5605         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5606     }
5607
5608     RegCloseKey(prodkey);
5609
5610     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5611     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5612     ok(pf_exists("msitest\\maximus"), "File deleted\n");
5613     ok(pf_exists("msitest"), "File deleted\n");
5614
5615     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5616     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5617
5618     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5619     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5620
5621     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5622     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5623
5624     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5625                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5626     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5627     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5628
5629     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5630     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5631
5632     /* complete install */
5633     r = MsiInstallProductA(msifile, "FULL=1");
5634     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5635     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5636     ok(pf_exists("msitest"), "File not installed\n");
5637
5638     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5639     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5640
5641     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5642     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5643
5644     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5645     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5646
5647     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5648                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5649     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5650     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5651
5652     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5654
5655     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5656     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5657     CHECK_REG_STR(prodkey, "InstallDate", date);
5658     CHECK_REG_STR(prodkey, "InstallSource", temp);
5659     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5660     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5661     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5662     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5663     CHECK_REG_STR(prodkey, "Comments", NULL);
5664     CHECK_REG_STR(prodkey, "Contact", NULL);
5665     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5666     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5667     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5668     CHECK_REG_STR(prodkey, "Readme", NULL);
5669     CHECK_REG_STR(prodkey, "Size", NULL);
5670     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5671     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5672     CHECK_REG_DWORD(prodkey, "Language", 1033);
5673     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5674     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5675     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5676     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5677     todo_wine
5678     {
5679         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5680     }
5681
5682     RegCloseKey(prodkey);
5683
5684     /* no UnpublishFeatures */
5685     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5686     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5687     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5688     ok(!pf_exists("msitest"), "Directory not deleted\n");
5689
5690     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5691     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5692
5693     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5694     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5695
5696     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5697     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5698
5699     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5700                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5701     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5702     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5703
5704     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5705     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5706
5707     /* complete install */
5708     r = MsiInstallProductA(msifile, "FULL=1");
5709     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5710     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5711     ok(pf_exists("msitest"), "File not installed\n");
5712
5713     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5714     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5715
5716     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5717     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5718
5719     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5720     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5721
5722     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5723                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5724     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5725     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5726
5727     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5729
5730     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5731     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5732     CHECK_REG_STR(prodkey, "InstallDate", date);
5733     CHECK_REG_STR(prodkey, "InstallSource", temp);
5734     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5735     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5736     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5737     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5738     CHECK_REG_STR(prodkey, "Comments", NULL);
5739     CHECK_REG_STR(prodkey, "Contact", NULL);
5740     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5741     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5742     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5743     CHECK_REG_STR(prodkey, "Readme", NULL);
5744     CHECK_REG_STR(prodkey, "Size", NULL);
5745     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5746     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5747     CHECK_REG_DWORD(prodkey, "Language", 1033);
5748     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5749     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5750     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5751     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5752     todo_wine
5753     {
5754         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5755     }
5756
5757     RegCloseKey(prodkey);
5758
5759     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
5760     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
5761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5762     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
5763     todo_wine ok(pf_exists("msitest"), "Directory deleted\n");
5764
5765     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5766     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5767
5768     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5769     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5770
5771     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5772     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5773
5774     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5775                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5777     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5778
5779     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5780     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5781
5782     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5783     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5784     CHECK_REG_STR(prodkey, "InstallDate", date);
5785     CHECK_REG_STR(prodkey, "InstallSource", temp);
5786     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5787     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5788     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5789     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5790     CHECK_REG_STR(prodkey, "Comments", NULL);
5791     CHECK_REG_STR(prodkey, "Contact", NULL);
5792     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5793     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5794     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5795     CHECK_REG_STR(prodkey, "Readme", NULL);
5796     CHECK_REG_STR(prodkey, "Size", NULL);
5797     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5798     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5799     CHECK_REG_DWORD(prodkey, "Language", 1033);
5800     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5801     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5802     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5803     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5804     todo_wine
5805     {
5806         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5807     }
5808
5809     RegCloseKey(prodkey);
5810
5811     /* complete install */
5812     r = MsiInstallProductA(msifile, "FULL=1");
5813     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5814     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5815     ok(pf_exists("msitest"), "File not installed\n");
5816
5817     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5818     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5819
5820     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5821     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5822
5823     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5824     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5825
5826     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5827                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5829     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5830
5831     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5832     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5833
5834     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5835     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5836     CHECK_REG_STR(prodkey, "InstallDate", date);
5837     CHECK_REG_STR(prodkey, "InstallSource", temp);
5838     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5839     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5840     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5841     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5842     CHECK_REG_STR(prodkey, "Comments", NULL);
5843     CHECK_REG_STR(prodkey, "Contact", NULL);
5844     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5845     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5846     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5847     CHECK_REG_STR(prodkey, "Readme", NULL);
5848     CHECK_REG_STR(prodkey, "Size", NULL);
5849     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5850     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5851     CHECK_REG_DWORD(prodkey, "Language", 1033);
5852     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5853     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5854     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5855     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5856     todo_wine
5857     {
5858         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
5859     }
5860
5861     RegCloseKey(prodkey);
5862
5863     /* UnpublishFeatures, both features removed */
5864     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
5865     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5866     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5867     ok(!pf_exists("msitest"), "Directory not deleted\n");
5868
5869     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5870     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5871
5872     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5873     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5874
5875     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5876     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5877
5878     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5879                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5880     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5881     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5882
5883     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5884     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5885
5886     /* complete install */
5887     r = MsiInstallProductA(msifile, "FULL=1");
5888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5889     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5890     ok(pf_exists("msitest"), "File not installed\n");
5891
5892     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5893     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
5894
5895     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5896     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5897
5898     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5899     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5900
5901     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5902                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5903     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5904     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
5905
5906     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5908
5909     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
5910     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
5911     CHECK_REG_STR(prodkey, "InstallDate", date);
5912     CHECK_REG_STR(prodkey, "InstallSource", temp);
5913     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5914     CHECK_REG_STR(prodkey, "Publisher", "Wine");
5915     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5916     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
5917     CHECK_REG_STR(prodkey, "Comments", NULL);
5918     CHECK_REG_STR(prodkey, "Contact", NULL);
5919     CHECK_REG_STR(prodkey, "HelpLink", NULL);
5920     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
5921     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
5922     CHECK_REG_STR(prodkey, "Readme", NULL);
5923     CHECK_REG_STR(prodkey, "Size", NULL);
5924     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
5925     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
5926     CHECK_REG_DWORD(prodkey, "Language", 1033);
5927     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
5928     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
5929     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
5930     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
5931     todo_wine
5932     {
5933         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
5934     }
5935
5936     RegCloseKey(prodkey);
5937
5938     /* complete uninstall */
5939     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
5940     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5941     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
5942     ok(!pf_exists("msitest"), "Directory not deleted\n");
5943
5944     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
5945     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5946
5947     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
5948     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5949
5950     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
5951     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5952
5953     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
5954                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
5955     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5956     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
5957
5958     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
5959     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5960
5961     /* make sure 'Program Files\msitest' is removed */
5962     delete_pfmsitest_files();
5963
5964     RegCloseKey(uninstall);
5965     DeleteFile(msifile);
5966     DeleteFile("msitest\\maximus");
5967     RemoveDirectory("msitest");
5968 }
5969
5970 static void test_publishsourcelist(void)
5971 {
5972     UINT r;
5973     DWORD size;
5974     CHAR value[MAX_PATH];
5975     CHAR path[MAX_PATH];
5976     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
5977
5978     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
5979     {
5980         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
5981         return;
5982     }
5983
5984     CreateDirectoryA("msitest", NULL);
5985     create_file("msitest\\maximus", 500);
5986
5987     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
5988
5989     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5990
5991     r = MsiInstallProductA(msifile, NULL);
5992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5993     ok(pf_exists("msitest\\maximus"), "File not installed\n");
5994     ok(pf_exists("msitest"), "File not installed\n");
5995
5996     /* nothing published */
5997     size = MAX_PATH;
5998     lstrcpyA(value, "aaa");
5999     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6000                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6001     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6002     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6003     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6004
6005     size = MAX_PATH;
6006     lstrcpyA(value, "aaa");
6007     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6008                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6009     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6010     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6011     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6012
6013     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
6014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6015     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6016     ok(pf_exists("msitest"), "File not installed\n");
6017
6018     /* after RegisterProduct */
6019     size = MAX_PATH;
6020     lstrcpyA(value, "aaa");
6021     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6022                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6023     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6024     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6025     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6026
6027     size = MAX_PATH;
6028     lstrcpyA(value, "aaa");
6029     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6030                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6031     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6032     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6033     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6034
6035     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
6036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6037     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6038     ok(pf_exists("msitest"), "File not installed\n");
6039
6040     /* after ProcessComponents */
6041     size = MAX_PATH;
6042     lstrcpyA(value, "aaa");
6043     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6044                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6045     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6046     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6047     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6048
6049     size = MAX_PATH;
6050     lstrcpyA(value, "aaa");
6051     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6052                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6053     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6054     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6055     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6056
6057     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
6058     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6059     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6060     ok(pf_exists("msitest"), "File not installed\n");
6061
6062     /* after PublishFeatures */
6063     size = MAX_PATH;
6064     lstrcpyA(value, "aaa");
6065     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6066                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6067     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6068     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6069     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6070
6071     size = MAX_PATH;
6072     lstrcpyA(value, "aaa");
6073     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6074                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6075     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6076     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
6077     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
6078
6079     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
6080     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6081     ok(pf_exists("msitest\\maximus"), "File not installed\n");
6082     ok(pf_exists("msitest"), "File not installed\n");
6083
6084     /* after PublishProduct */
6085     size = MAX_PATH;
6086     lstrcpyA(value, "aaa");
6087     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6088                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
6089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6090     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
6091     ok(size == 11, "Expected 11, got %d\n", size);
6092
6093     size = MAX_PATH;
6094     lstrcpyA(value, "aaa");
6095     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6096                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
6097     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6098     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
6099     ok(size == 0, "Expected 0, got %d\n", size);
6100
6101     size = MAX_PATH;
6102     lstrcpyA(value, "aaa");
6103     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6104                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
6105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6106     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
6107     ok(size == 0, "Expected 0, got %d\n", size);
6108
6109     lstrcpyA(path, CURR_DIR);
6110     lstrcatA(path, "\\");
6111
6112     size = MAX_PATH;
6113     lstrcpyA(value, "aaa");
6114     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6115                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
6116     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6117     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
6118     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
6119
6120     size = MAX_PATH;
6121     lstrcpyA(value, "aaa");
6122     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6123                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
6124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6125     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
6126     ok(size == 1, "Expected 1, got %d\n", size);
6127
6128     size = MAX_PATH;
6129     lstrcpyA(value, "aaa");
6130     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6131                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
6132     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6133     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
6134     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
6135
6136     size = MAX_PATH;
6137     lstrcpyA(value, "aaa");
6138     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6139                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
6140     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6141     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
6142     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
6143
6144     size = MAX_PATH;
6145     lstrcpyA(value, "aaa");
6146     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
6147                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
6148     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
6149     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
6150     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
6151
6152     /* complete uninstall */
6153     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
6154     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6155     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
6156     ok(!pf_exists("msitest"), "Directory not deleted\n");
6157
6158     /* make sure 'Program Files\msitest' is removed */
6159     delete_pfmsitest_files();
6160
6161     DeleteFile(msifile);
6162     DeleteFile("msitest\\maximus");
6163     RemoveDirectory("msitest");
6164 }
6165
6166 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
6167 {
6168     MSIHANDLE hview = 0;
6169     UINT r;
6170
6171     r = MsiDatabaseOpenView(hdb, query, &hview);
6172     if(r != ERROR_SUCCESS)
6173         return r;
6174
6175     r = MsiViewExecute(hview, hrec);
6176     if(r == ERROR_SUCCESS)
6177         r = MsiViewClose(hview);
6178     MsiCloseHandle(hview);
6179     return r;
6180 }
6181
6182 static void set_transform_summary_info(void)
6183 {
6184     UINT r;
6185     MSIHANDLE suminfo = 0;
6186
6187     /* build summary info */
6188     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
6189     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
6190
6191     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
6192     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
6193
6194     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
6195                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
6196                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
6197                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
6198     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
6199
6200     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
6201     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
6202
6203     r = MsiSummaryInfoPersist(suminfo);
6204     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
6205
6206     r = MsiCloseHandle(suminfo);
6207     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
6208 }
6209
6210 static void generate_transform(void)
6211 {
6212     MSIHANDLE hdb1, hdb2;
6213     LPCSTR query;
6214     UINT r;
6215
6216     /* start with two identical databases */
6217     CopyFile(msifile, msifile2, FALSE);
6218
6219     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
6220     ok(r == ERROR_SUCCESS , "Failed to create database\n");
6221
6222     r = MsiDatabaseCommit(hdb1);
6223     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
6224
6225     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
6226     ok(r == ERROR_SUCCESS , "Failed to create database\n");
6227
6228     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
6229     r = run_query(hdb1, 0, query);
6230     ok(r == ERROR_SUCCESS, "failed to add property\n");
6231
6232     /* database needs to be committed */
6233     MsiDatabaseCommit(hdb1);
6234
6235     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
6236     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
6237
6238 #if 0  /* not implemented in wine yet */
6239     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
6240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6241 #endif
6242
6243     MsiCloseHandle(hdb1);
6244     MsiCloseHandle(hdb2);
6245 }
6246
6247 /* data for generating a transform */
6248
6249 /* tables transform names - encoded as they would be in an msi database file */
6250 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
6251 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
6252 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
6253
6254 /* data in each table */
6255 static const char data1[] = /* _StringData */
6256     "propval";  /* all the strings squashed together */
6257
6258 static const WCHAR data2[] = { /* _StringPool */
6259 /*  len, refs */
6260     0,   0,    /* string 0 ''     */
6261     4,   1,    /* string 1 'prop' */
6262     3,   1,    /* string 2 'val'  */
6263 };
6264
6265 static const WCHAR data3[] = { /* Property */
6266     0x0201, 0x0001, 0x0002,
6267 };
6268
6269 static const struct {
6270     LPCWSTR name;
6271     const void *data;
6272     DWORD size;
6273 } table_transform_data[] =
6274 {
6275     { name1, data1, sizeof data1 - 1 },
6276     { name2, data2, sizeof data2 },
6277     { name3, data3, sizeof data3 },
6278 };
6279
6280 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
6281
6282 static void generate_transform_manual(void)
6283 {
6284     IStorage *stg = NULL;
6285     IStream *stm;
6286     WCHAR name[0x20];
6287     HRESULT r;
6288     DWORD i, count;
6289     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
6290
6291     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
6292
6293     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
6294
6295     r = StgCreateDocfile(name, mode, 0, &stg);
6296     ok(r == S_OK, "failed to create storage\n");
6297     if (!stg)
6298         return;
6299
6300     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
6301     ok(r == S_OK, "failed to set storage type\n");
6302
6303     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
6304     {
6305         r = IStorage_CreateStream(stg, table_transform_data[i].name,
6306                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
6307         if (FAILED(r))
6308         {
6309             ok(0, "failed to create stream %08x\n", r);
6310             continue;
6311         }
6312
6313         r = IStream_Write(stm, table_transform_data[i].data,
6314                           table_transform_data[i].size, &count);
6315         if (FAILED(r) || count != table_transform_data[i].size)
6316             ok(0, "failed to write stream\n");
6317         IStream_Release(stm);
6318     }
6319
6320     IStorage_Release(stg);
6321
6322     set_transform_summary_info();
6323 }
6324
6325 static void test_transformprop(void)
6326 {
6327     UINT r;
6328
6329     CreateDirectoryA("msitest", NULL);
6330     create_file("msitest\\augustus", 500);
6331
6332     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
6333
6334     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6335
6336     r = MsiInstallProductA(msifile, NULL);
6337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6338     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6339     ok(!delete_pf("msitest", FALSE), "File installed\n");
6340
6341     if (0)
6342         generate_transform();
6343     else
6344         generate_transform_manual();
6345
6346     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
6347     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6348     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6349     ok(delete_pf("msitest", FALSE), "File not installed\n");
6350
6351     /* Delete the files in the temp (current) folder */
6352     DeleteFile(msifile);
6353     DeleteFile(msifile2);
6354     DeleteFile(mstfile);
6355     DeleteFile("msitest\\augustus");
6356     RemoveDirectory("msitest");
6357 }
6358
6359 static void test_currentworkingdir(void)
6360 {
6361     UINT r;
6362     CHAR drive[MAX_PATH], path[MAX_PATH];
6363     LPSTR ptr;
6364
6365     CreateDirectoryA("msitest", NULL);
6366     create_file("msitest\\augustus", 500);
6367
6368     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
6369
6370     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6371
6372     CreateDirectoryA("diffdir", NULL);
6373     SetCurrentDirectoryA("diffdir");
6374
6375     sprintf(path, "..\\%s", msifile);
6376     r = MsiInstallProductA(path, NULL);
6377     todo_wine
6378     {
6379         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
6380         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6381         ok(!delete_pf("msitest", FALSE), "File installed\n");
6382     }
6383
6384     sprintf(path, "%s\\%s", CURR_DIR, msifile);
6385     r = MsiInstallProductA(path, NULL);
6386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6387     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6388     ok(delete_pf("msitest", FALSE), "File not installed\n");
6389
6390     lstrcpyA(drive, CURR_DIR);
6391     drive[2] = '\\';
6392     drive[3] = '\0';
6393     SetCurrentDirectoryA(drive);
6394
6395     lstrcpy(path, CURR_DIR);
6396     if (path[lstrlenA(path) - 1] != '\\')
6397         lstrcatA(path, "\\");
6398     lstrcatA(path, msifile);
6399     ptr = strchr(path, ':');
6400     ptr +=2;
6401
6402     r = MsiInstallProductA(ptr, NULL);
6403     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6404     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6405     ok(delete_pf("msitest", FALSE), "File not installed\n");
6406
6407     SetCurrentDirectoryA(CURR_DIR);
6408
6409     DeleteFile(msifile);
6410     DeleteFile("msitest\\augustus");
6411     RemoveDirectory("msitest");
6412     RemoveDirectory("diffdir");
6413 }
6414
6415 static void set_admin_summary_info(const CHAR *name)
6416 {
6417     MSIHANDLE db, summary;
6418     UINT r;
6419
6420     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
6421     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6422
6423     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
6424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6425
6426     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
6427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6428
6429     /* write the summary changes back to the stream */
6430     r = MsiSummaryInfoPersist(summary);
6431     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6432
6433     MsiCloseHandle(summary);
6434
6435     r = MsiDatabaseCommit(db);
6436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6437
6438     MsiCloseHandle(db);
6439 }
6440
6441 static void test_admin(void)
6442 {
6443     UINT r;
6444
6445     CreateDirectoryA("msitest", NULL);
6446     create_file("msitest\\augustus", 500);
6447
6448     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
6449     set_admin_summary_info(msifile);
6450
6451     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6452
6453     r = MsiInstallProductA(msifile, NULL);
6454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6455     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6456     ok(!delete_pf("msitest", FALSE), "File installed\n");
6457     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
6458     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
6459
6460     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
6461     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6462     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6463     ok(!delete_pf("msitest", FALSE), "File installed\n");
6464     todo_wine
6465     {
6466         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
6467         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
6468     }
6469
6470     DeleteFile(msifile);
6471     DeleteFile("msitest\\augustus");
6472     RemoveDirectory("msitest");
6473 }
6474
6475 static void set_admin_property_stream(LPCSTR file)
6476 {
6477     IStorage *stg;
6478     IStream *stm;
6479     WCHAR fileW[MAX_PATH];
6480     HRESULT hr;
6481     DWORD count;
6482     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
6483
6484     /* AdminProperties */
6485     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
6486     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
6487         'M','y','P','r','o','p','=','4','2',0};
6488
6489     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
6490
6491     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
6492     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6493     if (!stg)
6494         return;
6495
6496     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
6497     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6498
6499     hr = IStream_Write(stm, data, sizeof(data), &count);
6500     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
6501
6502     IStream_Release(stm);
6503     IStorage_Release(stg);
6504 }
6505
6506 static void test_adminprops(void)
6507 {
6508     UINT r;
6509
6510     CreateDirectoryA("msitest", NULL);
6511     create_file("msitest\\augustus", 500);
6512
6513     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
6514     set_admin_summary_info(msifile);
6515     set_admin_property_stream(msifile);
6516
6517     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6518
6519     r = MsiInstallProductA(msifile, NULL);
6520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6521     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6522     ok(delete_pf("msitest", FALSE), "File installed\n");
6523
6524     DeleteFile(msifile);
6525     DeleteFile("msitest\\augustus");
6526     RemoveDirectory("msitest");
6527 }
6528
6529 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
6530 {
6531     CHAR path[MAX_PATH];
6532
6533     lstrcpyA(path, PROG_FILES_DIR);
6534     lstrcatA(path, "\\");
6535     lstrcatA(path, file);
6536
6537     if (is_file)
6538         create_file_data(path, data, 500);
6539     else
6540         CreateDirectoryA(path, NULL);
6541 }
6542
6543 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
6544
6545 static void test_removefiles(void)
6546 {
6547     UINT r;
6548
6549     CreateDirectoryA("msitest", NULL);
6550     create_file("msitest\\hydrogen", 500);
6551     create_file("msitest\\helium", 500);
6552     create_file("msitest\\lithium", 500);
6553
6554     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
6555
6556     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6557
6558     r = MsiInstallProductA(msifile, NULL);
6559     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6560     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6561     ok(!pf_exists("msitest\\helium"), "File installed\n");
6562     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6563     ok(pf_exists("msitest"), "File not installed\n");
6564
6565     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6567     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6568     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
6569     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6570     ok(delete_pf("msitest", FALSE), "File deleted\n");
6571
6572     create_pf("msitest", FALSE);
6573     create_pf("msitest\\hydrogen", TRUE);
6574     create_pf("msitest\\helium", TRUE);
6575     create_pf("msitest\\lithium", TRUE);
6576
6577     r = MsiInstallProductA(msifile, NULL);
6578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6579     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6580     ok(pf_exists("msitest\\helium"), "File not installed\n");
6581     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6582     ok(pf_exists("msitest"), "File not installed\n");
6583
6584     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6585     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6586     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
6587     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
6588     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6589     ok(delete_pf("msitest", FALSE), "File deleted\n");
6590
6591     create_pf("msitest", FALSE);
6592     create_pf("msitest\\furlong", TRUE);
6593     create_pf("msitest\\firkin", TRUE);
6594     create_pf("msitest\\fortnight", TRUE);
6595     create_pf("msitest\\becquerel", TRUE);
6596     create_pf("msitest\\dioptre", TRUE);
6597     create_pf("msitest\\attoparsec", TRUE);
6598     create_pf("msitest\\storeys", TRUE);
6599     create_pf("msitest\\block", TRUE);
6600     create_pf("msitest\\siriometer", TRUE);
6601     create_pf("msitest\\cabout", FALSE);
6602     create_pf("msitest\\cabout\\blocker", TRUE);
6603
6604     r = MsiInstallProductA(msifile, NULL);
6605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6606     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6607     ok(!pf_exists("msitest\\helium"), "File installed\n");
6608     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6609     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
6610     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
6611     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
6612     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
6613     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
6614     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
6615     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
6616     ok(!pf_exists("msitest\\block"), "File not deleted\n");
6617     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
6618     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
6619     ok(pf_exists("msitest"), "File not installed\n");
6620
6621     create_pf("msitest\\furlong", TRUE);
6622     create_pf("msitest\\firkin", TRUE);
6623     create_pf("msitest\\fortnight", TRUE);
6624     create_pf("msitest\\storeys", TRUE);
6625     create_pf("msitest\\block", TRUE);
6626     create_pf("msitest\\siriometer", TRUE);
6627
6628     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6629     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6630     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
6631     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
6632     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
6633     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
6634     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
6635     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
6636     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
6637     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
6638     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
6639     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
6640     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
6641     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
6642     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6643     ok(pf_exists("msitest"), "Directory deleted\n");
6644
6645     r = MsiInstallProductA(msifile, NULL);
6646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6647     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
6648     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
6649     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
6650     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
6651     ok(pf_exists("msitest"), "Directory deleted\n");
6652
6653     delete_pf("msitest\\cabout\\blocker", TRUE);
6654
6655     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6657     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
6658     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
6659
6660     DeleteFile(msifile);
6661     DeleteFile("msitest\\hydrogen");
6662     DeleteFile("msitest\\helium");
6663     DeleteFile("msitest\\lithium");
6664     RemoveDirectory("msitest");
6665 }
6666
6667 static void test_movefiles(void)
6668 {
6669     UINT r;
6670     char props[MAX_PATH];
6671
6672     CreateDirectoryA("msitest", NULL);
6673     create_file("msitest\\augustus", 100);
6674     create_file("cameroon", 100);
6675     create_file("djibouti", 100);
6676     create_file("egypt", 100);
6677     create_file("finland", 100);
6678     create_file("gambai", 100);
6679     create_file("honduras", 100);
6680     create_file("msitest\\india", 100);
6681     create_file("japan", 100);
6682     create_file("kenya", 100);
6683     CreateDirectoryA("latvia", NULL);
6684     create_file("nauru", 100);
6685     create_file("peru", 100);
6686     create_file("apple", 100);
6687     create_file("application", 100);
6688     create_file("ape", 100);
6689     create_file("foo", 100);
6690     create_file("fao", 100);
6691     create_file("fbod", 100);
6692     create_file("budding", 100);
6693     create_file("buddy", 100);
6694     create_file("bud", 100);
6695     create_file("bar", 100);
6696     create_file("bur", 100);
6697     create_file("bird", 100);
6698
6699     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
6700
6701     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
6702
6703     /* if the source or dest property is not a full path,
6704      * windows tries to access it as a network resource
6705      */
6706
6707     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
6708             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
6709             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
6710
6711     r = MsiInstallProductA(msifile, props);
6712     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6713     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6714     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
6715     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
6716     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
6717     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
6718     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
6719     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
6720     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
6721     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
6722     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
6723     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
6724     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
6725     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
6726     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
6727     /* either apple or application will be moved depending on directory order */
6728     if (!delete_pf("msitest\\apple", TRUE))
6729         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
6730     else
6731         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
6732     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
6733     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
6734     /* either fao or foo will be moved depending on directory order */
6735     if (delete_pf("msitest\\foo", TRUE))
6736         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
6737     else
6738         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
6739     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
6740     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
6741     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
6742     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
6743     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
6744     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
6745     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
6746     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
6747     ok(delete_pf("msitest", FALSE), "File not installed\n");
6748     ok(DeleteFileA("cameroon"), "File moved\n");
6749     ok(!DeleteFileA("djibouti"), "File not moved\n");
6750     ok(DeleteFileA("egypt"), "File moved\n");
6751     ok(DeleteFileA("finland"), "File moved\n");
6752     ok(DeleteFileA("gambai"), "File moved\n");
6753     ok(!DeleteFileA("honduras"), "File not moved\n");
6754     ok(DeleteFileA("msitest\\india"), "File moved\n");
6755     ok(DeleteFileA("japan"), "File moved\n");
6756     ok(!DeleteFileA("kenya"), "File not moved\n");
6757     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
6758     ok(!DeleteFileA("nauru"), "File not moved\n");
6759     ok(!DeleteFileA("peru"), "File not moved\n");
6760     ok(!DeleteFileA("apple"), "File not moved\n");
6761     ok(!DeleteFileA("application"), "File not moved\n");
6762     ok(DeleteFileA("ape"), "File moved\n");
6763     ok(!DeleteFileA("foo"), "File not moved\n");
6764     ok(!DeleteFileA("fao"), "File not moved\n");
6765     ok(DeleteFileA("fbod"), "File moved\n");
6766     ok(!DeleteFileA("budding"), "File not moved\n");
6767     ok(!DeleteFileA("buddy"), "File not moved\n");
6768     ok(DeleteFileA("bud"), "File moved\n");
6769     ok(!DeleteFileA("bar"), "File not moved\n");
6770     ok(!DeleteFileA("bur"), "File not moved\n");
6771     ok(DeleteFileA("bird"), "File moved\n");
6772
6773     DeleteFile("msitest\\augustus");
6774     RemoveDirectory("msitest");
6775     DeleteFile(msifile);
6776 }
6777
6778 static void test_missingcab(void)
6779 {
6780     UINT r;
6781
6782     CreateDirectoryA("msitest", NULL);
6783     create_file("msitest\\augustus", 500);
6784     create_file("maximus", 500);
6785
6786     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
6787
6788     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6789
6790     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6791
6792     create_pf("msitest", FALSE);
6793     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6794
6795     r = MsiInstallProductA(msifile, NULL);
6796     ok(r == ERROR_SUCCESS ||
6797        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
6798        "Expected ERROR_SUCCESS, got %u\n", r);
6799     if (r == ERROR_SUCCESS)
6800     {
6801       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6802       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6803     }
6804     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
6805     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
6806     ok(delete_pf("msitest", FALSE), "File not installed\n");
6807
6808     create_pf("msitest", FALSE);
6809     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
6810     create_pf("msitest\\gaius", TRUE);
6811
6812     r = MsiInstallProductA(msifile, "GAIUS=1");
6813     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6814     todo_wine
6815     {
6816         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
6817         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6818     }
6819     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
6820     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
6821     ok(delete_pf("msitest", FALSE), "File not installed\n");
6822
6823     DeleteFile("msitest\\augustus");
6824     RemoveDirectory("msitest");
6825     DeleteFile("maximus");
6826     DeleteFile("test1.cab");
6827     DeleteFile(msifile);
6828 }
6829
6830 static void test_duplicatefiles(void)
6831 {
6832     UINT r;
6833
6834     CreateDirectoryA("msitest", NULL);
6835     create_file("msitest\\maximus", 500);
6836     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
6837
6838     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6839
6840     /* fails if the destination folder is not a valid property */
6841
6842     r = MsiInstallProductA(msifile, NULL);
6843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6844     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
6845     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
6846     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
6847     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
6848     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
6849     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
6850     ok(delete_pf("msitest", FALSE), "File not installed\n");
6851
6852     DeleteFile("msitest\\maximus");
6853     RemoveDirectory("msitest");
6854     DeleteFile(msifile);
6855 }
6856
6857 static void test_writeregistryvalues(void)
6858 {
6859     UINT r;
6860     LONG res;
6861     HKEY hkey;
6862     DWORD type, size;
6863     CHAR path[MAX_PATH];
6864
6865     CreateDirectoryA("msitest", NULL);
6866     create_file("msitest\\augustus", 500);
6867
6868     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
6869
6870     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6871
6872     r = MsiInstallProductA(msifile, NULL);
6873     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6874     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6875     ok(delete_pf("msitest", FALSE), "File installed\n");
6876
6877     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
6878     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6879
6880     size = MAX_PATH;
6881     type = REG_MULTI_SZ;
6882     memset(path, 'a', MAX_PATH);
6883     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
6884     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6885     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
6886     ok(size == 15, "Expected 15, got %d\n", size);
6887     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
6888
6889     DeleteFile(msifile);
6890     DeleteFile("msitest\\augustus");
6891     RemoveDirectory("msitest");
6892
6893     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
6894     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
6895 }
6896
6897 static void test_sourcefolder(void)
6898 {
6899     UINT r;
6900
6901     CreateDirectoryA("msitest", NULL);
6902     create_file("augustus", 500);
6903
6904     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
6905
6906     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6907
6908     r = MsiInstallProductA(msifile, NULL);
6909     ok(r == ERROR_INSTALL_FAILURE,
6910        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6911     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6912     todo_wine
6913     {
6914         ok(!delete_pf("msitest", FALSE), "File installed\n");
6915     }
6916
6917     RemoveDirectoryA("msitest");
6918
6919     r = MsiInstallProductA(msifile, NULL);
6920     ok(r == ERROR_INSTALL_FAILURE,
6921        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6922     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
6923     todo_wine
6924     {
6925         ok(!delete_pf("msitest", FALSE), "File installed\n");
6926     }
6927
6928     DeleteFile(msifile);
6929     DeleteFile("augustus");
6930 }
6931
6932 static void test_customaction51(void)
6933 {
6934     UINT r;
6935
6936     CreateDirectoryA("msitest", NULL);
6937     create_file("msitest\\augustus", 500);
6938
6939     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6940
6941     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6942
6943     r = MsiInstallProductA(msifile, NULL);
6944     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6945     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6946     ok(delete_pf("msitest", FALSE), "File installed\n");
6947
6948     DeleteFile(msifile);
6949     DeleteFile("msitest\\augustus");
6950     RemoveDirectory("msitest");
6951 }
6952
6953 static void test_installstate(void)
6954 {
6955     UINT r;
6956
6957     CreateDirectoryA("msitest", NULL);
6958     create_file("msitest\\alpha", 500);
6959     create_file("msitest\\beta", 500);
6960     create_file("msitest\\gamma", 500);
6961     create_file("msitest\\theta", 500);
6962     create_file("msitest\\delta", 500);
6963     create_file("msitest\\epsilon", 500);
6964     create_file("msitest\\zeta", 500);
6965     create_file("msitest\\iota", 500);
6966     create_file("msitest\\eta", 500);
6967     create_file("msitest\\kappa", 500);
6968     create_file("msitest\\lambda", 500);
6969     create_file("msitest\\mu", 500);
6970
6971     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
6972
6973     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6974
6975     r = MsiInstallProductA(msifile, NULL);
6976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6977     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6978     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6979     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6980     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6981     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6982     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
6983     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
6984     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
6985     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
6986     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
6987     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
6988     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
6989     ok(delete_pf("msitest", FALSE), "File not installed\n");
6990
6991     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
6992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6993     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
6994     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
6995     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
6996     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
6997     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
6998     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
6999     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
7000     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
7001     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
7002     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
7003     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
7004     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
7005     ok(delete_pf("msitest", FALSE), "File not installed\n");
7006
7007     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
7008     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7009     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
7010     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
7011     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
7012     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
7013     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
7014     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
7015     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
7016     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
7017     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
7018     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
7019     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
7020     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
7021     ok(delete_pf("msitest", FALSE), "File not installed\n");
7022
7023     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
7024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7025     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
7026     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
7027     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
7028     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
7029     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
7030     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
7031     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
7032     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
7033     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
7034     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
7035     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
7036     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
7037     ok(!delete_pf("msitest", FALSE), "File installed\n");
7038
7039     DeleteFile(msifile);
7040     DeleteFile("msitest\\alpha");
7041     DeleteFile("msitest\\beta");
7042     DeleteFile("msitest\\gamma");
7043     DeleteFile("msitest\\theta");
7044     DeleteFile("msitest\\delta");
7045     DeleteFile("msitest\\epsilon");
7046     DeleteFile("msitest\\zeta");
7047     DeleteFile("msitest\\iota");
7048     DeleteFile("msitest\\eta");
7049     DeleteFile("msitest\\kappa");
7050     DeleteFile("msitest\\lambda");
7051     DeleteFile("msitest\\mu");
7052     RemoveDirectory("msitest");
7053 }
7054
7055 struct sourcepathmap
7056 {
7057     BOOL sost; /* shortone\shorttwo */
7058     BOOL solt; /* shortone\longtwo */
7059     BOOL lost; /* longone\shorttwo */
7060     BOOL lolt; /* longone\longtwo */
7061     BOOL soste; /* shortone\shorttwo source exists */
7062     BOOL solte; /* shortone\longtwo source exists */
7063     BOOL loste; /* longone\shorttwo source exists */
7064     BOOL lolte; /* longone\longtwo source exists */
7065     UINT err;
7066     DWORD size;
7067 } spmap[256] =
7068 {
7069     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7070     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7071     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7072     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7073     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7074     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7075     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7076     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7077     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7078     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7079     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7080     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7081     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7082     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7083     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7084     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7085     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7086     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7087     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7088     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7089     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7090     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7091     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7092     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7093     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7094     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7095     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7096     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7097     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7098     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7099     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7100     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7101     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7102     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7103     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7104     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7105     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7106     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7107     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7108     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7109     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7110     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7111     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7112     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7113     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7114     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7115     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7116     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7117     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7118     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7119     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7120     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7121     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7122     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7123     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7124     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7125     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7126     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7127     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7128     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7129     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7130     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7131     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7132     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7133     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7134     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7135     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7136     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7137     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7138     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7139     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7140     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7141     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7142     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7143     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7144     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7145     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7146     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7147     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7148     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7149     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7150     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7151     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7152     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7153     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7154     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7155     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7156     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7157     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7158     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7159     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7160     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7161     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7162     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7163     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7164     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7165     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7166     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7167     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7168     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7169     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7170     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7171     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7172     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7173     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7174     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7175     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7176     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7177     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7178     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7179     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7180     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7181     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7182     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7183     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7184     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7185     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7186     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7187     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7188     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7189     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7190     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7191     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7192     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7193     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7194     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7195     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7196     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7197     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7198     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7199     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7200     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7201     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7202     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7203     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7204     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7205     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7206     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7207     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7208     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7209     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7210     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7211     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7212     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7213     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7214     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7215     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7216     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7217     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7218     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7219     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7220     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7221     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7222     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7223     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7224     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7225     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7226     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7227     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7228     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7229     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7230     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7231     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7232     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7233     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7234     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7235     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7236     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7237     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7238     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7239     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7240     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7241     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7242     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7243     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7244     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7245     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7246     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7247     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7248     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7249     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7250     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7251     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7252     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7253     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7254     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7255     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7256     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7257     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7258     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7259     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7260     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7261     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7262     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7263     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7264     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7265     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7266     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7267     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7268     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7269     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7270     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7271     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7272     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7273     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7274     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7275     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7276     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7277     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7278     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7279     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7280     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7281     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7282     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7283     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7284     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7285     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7286     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7287     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7288     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7289     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7290     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7291     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7292     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7293     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7294     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7295     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7296     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7297     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7298     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7299     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7300     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7301     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
7302     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7303     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
7304     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7305     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
7306     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7307     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
7308     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7309     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7310     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7311     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7312     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7313     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7314     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7315     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7316     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7317     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7318     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7319     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7320     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7321     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
7322     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
7323     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
7324     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
7325 };
7326
7327 static DWORD get_pf_file_size(LPCSTR file)
7328 {
7329     CHAR path[MAX_PATH];
7330     HANDLE hfile;
7331     DWORD size;
7332
7333     lstrcpyA(path, PROG_FILES_DIR);
7334     lstrcatA(path, "\\");
7335     lstrcatA(path, file);
7336
7337     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7338     if (hfile == INVALID_HANDLE_VALUE)
7339         return INVALID_FILE_SIZE;
7340
7341     size = GetFileSize(hfile, NULL);
7342     CloseHandle(hfile);
7343     return size;
7344 }
7345
7346 static void test_sourcepath(void)
7347 {
7348     UINT r, i;
7349
7350     if (!winetest_interactive)
7351     {
7352         skip("Run in interactive mode to run source path tests.\n");
7353         return;
7354     }
7355
7356     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
7357
7358     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7359
7360     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
7361     {
7362         if (spmap[i].sost)
7363         {
7364             CreateDirectoryA("shortone", NULL);
7365             CreateDirectoryA("shortone\\shorttwo", NULL);
7366         }
7367
7368         if (spmap[i].solt)
7369         {
7370             CreateDirectoryA("shortone", NULL);
7371             CreateDirectoryA("shortone\\longtwo", NULL);
7372         }
7373
7374         if (spmap[i].lost)
7375         {
7376             CreateDirectoryA("longone", NULL);
7377             CreateDirectoryA("longone\\shorttwo", NULL);
7378         }
7379
7380         if (spmap[i].lolt)
7381         {
7382             CreateDirectoryA("longone", NULL);
7383             CreateDirectoryA("longone\\longtwo", NULL);
7384         }
7385
7386         if (spmap[i].soste)
7387             create_file("shortone\\shorttwo\\augustus", 50);
7388         if (spmap[i].solte)
7389             create_file("shortone\\longtwo\\augustus", 100);
7390         if (spmap[i].loste)
7391             create_file("longone\\shorttwo\\augustus", 150);
7392         if (spmap[i].lolte)
7393             create_file("longone\\longtwo\\augustus", 200);
7394
7395         r = MsiInstallProductA(msifile, NULL);
7396         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
7397         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
7398            "%d: Expected %d, got %d\n", i, spmap[i].size,
7399            get_pf_file_size("msitest\\augustus"));
7400
7401         if (r == ERROR_SUCCESS)
7402         {
7403             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
7404             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
7405         }
7406         else
7407         {
7408             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
7409             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
7410         }
7411
7412         DeleteFileA("shortone\\shorttwo\\augustus");
7413         DeleteFileA("shortone\\longtwo\\augustus");
7414         DeleteFileA("longone\\shorttwo\\augustus");
7415         DeleteFileA("longone\\longtwo\\augustus");
7416         RemoveDirectoryA("shortone\\shorttwo");
7417         RemoveDirectoryA("shortone\\longtwo");
7418         RemoveDirectoryA("longone\\shorttwo");
7419         RemoveDirectoryA("longone\\longtwo");
7420         RemoveDirectoryA("shortone");
7421         RemoveDirectoryA("longone");
7422     }
7423
7424     DeleteFileA(msifile);
7425 }
7426
7427 static void test_MsiConfigureProductEx(void)
7428 {
7429     UINT r;
7430     LONG res;
7431     DWORD type, size;
7432     HKEY props, source;
7433     CHAR keypath[MAX_PATH * 2];
7434     CHAR localpack[MAX_PATH];
7435
7436     if (on_win9x)
7437     {
7438         win_skip("Different registry keys on Win9x and WinMe\n");
7439         return;
7440     }
7441
7442     CreateDirectoryA("msitest", NULL);
7443     create_file("msitest\\hydrogen", 500);
7444     create_file("msitest\\helium", 500);
7445     create_file("msitest\\lithium", 500);
7446
7447     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7448
7449     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7450
7451     /* NULL szProduct */
7452     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
7453                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7454     ok(r == ERROR_INVALID_PARAMETER,
7455        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7456
7457     /* empty szProduct */
7458     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
7459                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7460     ok(r == ERROR_INVALID_PARAMETER,
7461        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7462
7463     /* garbage szProduct */
7464     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
7465                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
7466     ok(r == ERROR_INVALID_PARAMETER,
7467        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7468
7469     /* guid without brackets */
7470     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7471                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7472                                "PROPVAR=42");
7473     ok(r == ERROR_INVALID_PARAMETER,
7474        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7475
7476     /* guid with brackets */
7477     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7478                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7479                                "PROPVAR=42");
7480     ok(r == ERROR_UNKNOWN_PRODUCT,
7481        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7482
7483     /* same length as guid, but random */
7484     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
7485                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7486                                "PROPVAR=42");
7487     ok(r == ERROR_UNKNOWN_PRODUCT,
7488        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7489
7490     /* product not installed yet */
7491     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7492                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7493                                "PROPVAR=42");
7494     ok(r == ERROR_UNKNOWN_PRODUCT,
7495        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7496
7497     /* install the product, per-user unmanaged */
7498     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7499     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7500     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7501     ok(pf_exists("msitest\\helium"), "File not installed\n");
7502     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7503     ok(pf_exists("msitest"), "File not installed\n");
7504
7505     /* product is installed per-user managed, remove it */
7506     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7507                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7508                                "PROPVAR=42");
7509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7510     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7511     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7512     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7513     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7514
7515     /* product has been removed */
7516     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7517                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7518                                "PROPVAR=42");
7519     ok(r == ERROR_UNKNOWN_PRODUCT,
7520        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7521
7522     /* install the product, machine */
7523     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7525     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7526     ok(pf_exists("msitest\\helium"), "File not installed\n");
7527     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7528     ok(pf_exists("msitest"), "File not installed\n");
7529
7530     /* product is installed machine, remove it */
7531     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7532                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7533                                "PROPVAR=42");
7534     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7535     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7536     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7537     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7538     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7539
7540     /* product has been removed */
7541     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7542                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
7543                                "PROPVAR=42");
7544     ok(r == ERROR_UNKNOWN_PRODUCT,
7545        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
7546
7547     /* install the product, machine */
7548     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7549     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7550     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7551     ok(pf_exists("msitest\\helium"), "File not installed\n");
7552     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7553     ok(pf_exists("msitest"), "File not installed\n");
7554
7555     DeleteFileA(msifile);
7556
7557     /* local msifile is removed */
7558     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7559                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7560                                "PROPVAR=42");
7561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7562     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7563     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7564     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7565     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7566
7567     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7568
7569     /* install the product, machine */
7570     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7572     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7573     ok(pf_exists("msitest\\helium"), "File not installed\n");
7574     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7575     ok(pf_exists("msitest"), "File not installed\n");
7576
7577     DeleteFileA(msifile);
7578
7579     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7580     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7581     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7582
7583     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7585
7586     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7587                          (const BYTE *)"C:\\idontexist.msi", 18);
7588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7589
7590     /* LocalPackage is used to find the cached msi package */
7591     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7592                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7593                                "PROPVAR=42");
7594     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7595        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7596     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7597     ok(pf_exists("msitest\\helium"), "File not installed\n");
7598     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7599     ok(pf_exists("msitest"), "File not installed\n");
7600
7601     RegCloseKey(props);
7602     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
7603
7604     /* LastUsedSource (local msi package) can be used as a last resort */
7605     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7606                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7607                                "PROPVAR=42");
7608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7609     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7610     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7611     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7612     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7613
7614     /* install the product, machine */
7615     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
7616     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7617     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7618     ok(pf_exists("msitest\\helium"), "File not installed\n");
7619     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7620     ok(pf_exists("msitest"), "File not installed\n");
7621
7622     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
7623     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7624     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
7625
7626     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
7627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7628
7629     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7630                          (const BYTE *)"C:\\idontexist.msi", 18);
7631     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7632
7633     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
7634     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
7635
7636     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
7637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7638
7639     type = REG_SZ;
7640     size = MAX_PATH;
7641     res = RegQueryValueExA(source, "PackageName", NULL, &type,
7642                            (LPBYTE)localpack, &size);
7643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7644
7645     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7646                          (const BYTE *)"idontexist.msi", 15);
7647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7648
7649     /* SourceList is altered */
7650     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7651                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7652                                "PROPVAR=42");
7653     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
7654        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
7655     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7656     ok(pf_exists("msitest\\helium"), "File not installed\n");
7657     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7658     ok(pf_exists("msitest"), "File not installed\n");
7659
7660     /* restore the SourceList */
7661     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
7662                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
7663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7664
7665     /* finally remove the product */
7666     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
7667                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
7668                                "PROPVAR=42");
7669     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7670     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7671     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7672     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7673     ok(!delete_pf("msitest", FALSE), "File not removed\n");
7674
7675     DeleteFileA(msifile);
7676     RegCloseKey(source);
7677     RegCloseKey(props);
7678     DeleteFileA("msitest\\hydrogen");
7679     DeleteFileA("msitest\\helium");
7680     DeleteFileA("msitest\\lithium");
7681     RemoveDirectoryA("msitest");
7682 }
7683
7684 static void test_missingcomponent(void)
7685 {
7686     UINT r;
7687
7688     CreateDirectoryA("msitest", NULL);
7689     create_file("msitest\\hydrogen", 500);
7690     create_file("msitest\\helium", 500);
7691     create_file("msitest\\lithium", 500);
7692     create_file("beryllium", 500);
7693
7694     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
7695
7696     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7697
7698     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
7699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7700     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
7701     ok(pf_exists("msitest\\helium"), "File not installed\n");
7702     ok(pf_exists("msitest\\lithium"), "File not installed\n");
7703     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7704     ok(pf_exists("msitest"), "File not installed\n");
7705
7706     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
7707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7708     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
7709     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
7710     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
7711     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
7712     ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
7713
7714     DeleteFileA(msifile);
7715     DeleteFileA("msitest\\hydrogen");
7716     DeleteFileA("msitest\\helium");
7717     DeleteFileA("msitest\\lithium");
7718     DeleteFileA("beryllium");
7719     RemoveDirectoryA("msitest");
7720 }
7721
7722 static void test_sourcedirprop(void)
7723 {
7724     UINT r;
7725     CHAR props[MAX_PATH];
7726
7727     CreateDirectoryA("msitest", NULL);
7728     create_file("msitest\\augustus", 500);
7729
7730     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
7731
7732     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7733
7734     r = MsiInstallProductA(msifile, NULL);
7735     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7736     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7737     ok(delete_pf("msitest", FALSE), "File installed\n");
7738
7739     DeleteFile("msitest\\augustus");
7740     RemoveDirectory("msitest");
7741
7742     CreateDirectoryA("altsource", NULL);
7743     CreateDirectoryA("altsource\\msitest", NULL);
7744     create_file("altsource\\msitest\\augustus", 500);
7745
7746     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
7747
7748     r = MsiInstallProductA(msifile, props);
7749     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7750     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
7751     ok(delete_pf("msitest", FALSE), "File installed\n");
7752
7753     DeleteFile(msifile);
7754     DeleteFile("altsource\\msitest\\augustus");
7755     RemoveDirectory("altsource\\msitest");
7756     RemoveDirectory("altsource");
7757 }
7758
7759 static void test_adminimage(void)
7760 {
7761     UINT r;
7762
7763     CreateDirectoryA("msitest", NULL);
7764     CreateDirectoryA("msitest\\first", NULL);
7765     CreateDirectoryA("msitest\\second", NULL);
7766     CreateDirectoryA("msitest\\cabout", NULL);
7767     CreateDirectoryA("msitest\\cabout\\new", NULL);
7768     create_file("msitest\\one.txt", 100);
7769     create_file("msitest\\first\\two.txt", 100);
7770     create_file("msitest\\second\\three.txt", 100);
7771     create_file("msitest\\cabout\\four.txt", 100);
7772     create_file("msitest\\cabout\\new\\five.txt", 100);
7773     create_file("msitest\\filename", 100);
7774     create_file("msitest\\service.exe", 100);
7775
7776     create_database_wordcount(msifile, ai_tables,
7777                               sizeof(ai_tables) / sizeof(msi_table),
7778                               msidbSumInfoSourceTypeAdminImage);
7779
7780     r = MsiInstallProductA(msifile, NULL);
7781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7782
7783     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
7784     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
7785     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
7786     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
7787     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
7788     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
7789     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
7790     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
7791     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
7792     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
7793     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
7794     ok(delete_pf("msitest", FALSE), "File not installed\n");
7795
7796     DeleteFileA("msitest.msi");
7797     DeleteFileA("msitest\\cabout\\new\\five.txt");
7798     DeleteFileA("msitest\\cabout\\four.txt");
7799     DeleteFileA("msitest\\second\\three.txt");
7800     DeleteFileA("msitest\\first\\two.txt");
7801     DeleteFileA("msitest\\one.txt");
7802     DeleteFileA("msitest\\service.exe");
7803     DeleteFileA("msitest\\filename");
7804     RemoveDirectoryA("msitest\\cabout\\new");
7805     RemoveDirectoryA("msitest\\cabout");
7806     RemoveDirectoryA("msitest\\second");
7807     RemoveDirectoryA("msitest\\first");
7808     RemoveDirectoryA("msitest");
7809 }
7810
7811 static void test_propcase(void)
7812 {
7813     UINT r;
7814
7815     CreateDirectoryA("msitest", NULL);
7816     create_file("msitest\\augustus", 500);
7817
7818     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
7819
7820     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
7821
7822     r = MsiInstallProductA(msifile, "MyProp=42");
7823     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7824     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
7825     ok(delete_pf("msitest", FALSE), "File not installed\n");
7826
7827     DeleteFile(msifile);
7828     DeleteFile("msitest\\augustus");
7829     RemoveDirectory("msitest");
7830 }
7831
7832 static void test_int_widths( void )
7833 {
7834     static const char int0[] = "int0\ni0\nint0\tint0\n1";
7835     static const char int1[] = "int1\ni1\nint1\tint1\n1";
7836     static const char int2[] = "int2\ni2\nint2\tint2\n1";
7837     static const char int3[] = "int3\ni3\nint3\tint3\n1";
7838     static const char int4[] = "int4\ni4\nint4\tint4\n1";
7839     static const char int5[] = "int5\ni5\nint5\tint5\n1";
7840     static const char int8[] = "int8\ni8\nint8\tint8\n1";
7841
7842     static const struct
7843     {
7844         const char  *data;
7845         unsigned int size;
7846         UINT         ret;
7847     }
7848     tests[] =
7849     {
7850         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
7851         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
7852         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
7853         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
7854         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
7855         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
7856         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
7857     };
7858
7859     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
7860     MSIHANDLE db;
7861     UINT r, i;
7862
7863     GetTempPathA(MAX_PATH, tmpdir);
7864     CreateDirectoryA(tmpdir, NULL);
7865
7866     strcpy(msitable, tmpdir);
7867     strcat(msitable, "\\msitable.idt");
7868
7869     strcpy(msidb, tmpdir);
7870     strcat(msidb, "\\msitest.msi");
7871
7872     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
7873     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7874
7875     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
7876     {
7877         write_file(msitable, tests[i].data, tests[i].size);
7878
7879         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
7880         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
7881
7882         r = MsiDatabaseCommit(db);
7883         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7884         DeleteFileA(msitable);
7885     }
7886
7887     MsiCloseHandle(db);
7888     DeleteFileA(msidb);
7889     RemoveDirectoryA(tmpdir);
7890 }
7891
7892 static void test_shortcut(void)
7893 {
7894     UINT r;
7895     HRESULT hr;
7896
7897     create_test_files();
7898     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
7899
7900     r = MsiInstallProductA(msifile, NULL);
7901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7902
7903     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
7904     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7905
7906     r = MsiInstallProductA(msifile, NULL);
7907     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7908
7909     CoUninitialize();
7910
7911     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7912     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
7913
7914     r = MsiInstallProductA(msifile, NULL);
7915     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7916
7917     CoUninitialize();
7918
7919     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
7920     delete_pf("msitest\\cabout\\new", FALSE);
7921     delete_pf("msitest\\cabout\\four.txt", TRUE);
7922     delete_pf("msitest\\cabout", FALSE);
7923     delete_pf("msitest\\changed\\three.txt", TRUE);
7924     delete_pf("msitest\\changed", FALSE);
7925     delete_pf("msitest\\first\\two.txt", TRUE);
7926     delete_pf("msitest\\first", FALSE);
7927     delete_pf("msitest\\filename", TRUE);
7928     delete_pf("msitest\\one.txt", TRUE);
7929     delete_pf("msitest\\service.exe", TRUE);
7930     delete_pf("msitest\\Shortcut.lnk", TRUE);
7931     delete_pf("msitest", FALSE);
7932     delete_test_files();
7933 }
7934
7935 static void test_envvar(void)
7936 {
7937     UINT r;
7938     HKEY env;
7939     LONG res;
7940     DWORD type, size;
7941     char buffer[16];
7942     UINT i;
7943
7944     if (on_win9x)
7945     {
7946         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
7947         return;
7948     }
7949
7950     create_test_files();
7951     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
7952
7953     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
7954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7955
7956     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
7957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7958
7959     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
7960     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7961
7962     r = MsiInstallProductA(msifile, NULL);
7963     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
7964
7965     type = REG_NONE;
7966     size = sizeof(buffer);
7967     buffer[0] = 0;
7968     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
7969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7970     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7971     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7972
7973     res = RegDeleteValueA(env, "MSITESTVAR1");
7974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7975
7976     type = REG_NONE;
7977     size = sizeof(buffer);
7978     buffer[0] = 0;
7979     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
7980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7981     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
7982     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
7983
7984     res = RegDeleteValueA(env, "MSITESTVAR2");
7985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7986
7987     res = RegDeleteValueA(env, "MSITESTVAR3");
7988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7989
7990     res = RegDeleteValueA(env, "MSITESTVAR4");
7991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7992
7993     res = RegDeleteValueA(env, "MSITESTVAR5");
7994     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7995
7996     res = RegDeleteValueA(env, "MSITESTVAR6");
7997     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
7998
7999     res = RegDeleteValueA(env, "MSITESTVAR7");
8000     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8001
8002     res = RegDeleteValueA(env, "MSITESTVAR8");
8003     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8004
8005     res = RegDeleteValueA(env, "MSITESTVAR9");
8006     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8007
8008     res = RegDeleteValueA(env, "MSITESTVAR10");
8009     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
8010
8011     i = 11;
8012     while (environment_dat_results[(i-11)]) {
8013         char name[20];
8014         sprintf(name, "MSITESTVAR%d", i);
8015
8016         type = REG_NONE;
8017         size = sizeof(buffer);
8018         buffer[0] = 0;
8019         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
8020         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
8021         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
8022         ok(!lstrcmp(buffer, environment_dat_results[(i-11)]), "%d: Expected %s, got %s\n",
8023            i, environment_dat_results[(i-11)], buffer);
8024
8025         res = RegDeleteValueA(env, name);
8026         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
8027         i++;
8028     }
8029
8030
8031     RegCloseKey(env);
8032     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
8033     delete_pf("msitest\\cabout\\new", FALSE);
8034     delete_pf("msitest\\cabout\\four.txt", TRUE);
8035     delete_pf("msitest\\cabout", FALSE);
8036     delete_pf("msitest\\changed\\three.txt", TRUE);
8037     delete_pf("msitest\\changed", FALSE);
8038     delete_pf("msitest\\first\\two.txt", TRUE);
8039     delete_pf("msitest\\first", FALSE);
8040     delete_pf("msitest\\filename", TRUE);
8041     delete_pf("msitest\\one.txt", TRUE);
8042     delete_pf("msitest\\service.exe", TRUE);
8043     delete_pf("msitest", FALSE);
8044     delete_test_files();
8045 }
8046
8047 static void test_preselected(void)
8048 {
8049     UINT r;
8050
8051     create_test_files();
8052     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
8053
8054     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
8055     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8056
8057     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8058     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
8059     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8060     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
8061     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8062     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
8063     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8064     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
8065     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8066     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8067     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8068     ok(delete_pf("msitest", FALSE), "File not installed\n");
8069
8070     r = MsiInstallProductA(msifile, NULL);
8071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8072
8073     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8074     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8075     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8076     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8077     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8078     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8079     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8080     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8081     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8082     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8083     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8084     ok(delete_pf("msitest", FALSE), "File not installed\n");
8085     delete_test_files();
8086 }
8087
8088 static void test_installed_prop(void)
8089 {
8090     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
8091     UINT r;
8092
8093     create_test_files();
8094     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
8095
8096     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8097
8098     r = MsiInstallProductA(msifile, "FULL=1");
8099     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8100
8101     r = MsiInstallProductA(msifile, "FULL=1");
8102     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8103
8104     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
8105     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8106
8107     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8108     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8109     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8110     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8111     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8112     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8113     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8114     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8115     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8116     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8117     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8118     ok(delete_pf("msitest", FALSE), "File not installed\n");
8119
8120     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8121     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8122
8123     delete_test_files();
8124 }
8125
8126 static void test_allusers_prop(void)
8127 {
8128     UINT r;
8129
8130     create_test_files();
8131     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
8132
8133     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8134
8135     /* ALLUSERS property unset */
8136     r = MsiInstallProductA(msifile, "FULL=1");
8137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8138
8139     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8140     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8141     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8142     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8143     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8144     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8145     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8146     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8147     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8148     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8149     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8150     ok(delete_pf("msitest", FALSE), "File not installed\n");
8151
8152     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8154
8155     delete_test_files();
8156
8157     create_test_files();
8158     create_database(msifile, aup2_tables, sizeof(aup2_tables) / sizeof(msi_table));
8159
8160     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8161
8162     /* ALLUSERS property set to 1 */
8163     r = MsiInstallProductA(msifile, "FULL=1");
8164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8165
8166     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8167     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8168     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8169     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8170     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8171     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8172     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8173     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8174     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8175     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8176     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8177     ok(delete_pf("msitest", FALSE), "File not installed\n");
8178
8179     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8180     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8181
8182     delete_test_files();
8183
8184     create_test_files();
8185     create_database(msifile, aup3_tables, sizeof(aup3_tables) / sizeof(msi_table));
8186
8187     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8188
8189     /* ALLUSERS property set to 2 */
8190     r = MsiInstallProductA(msifile, "FULL=1");
8191     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8192
8193     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8194     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8195     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8196     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8197     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8198     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8199     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8200     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8201     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8202     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8203     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8204     ok(delete_pf("msitest", FALSE), "File not installed\n");
8205
8206     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8207     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8208
8209     delete_test_files();
8210
8211     create_test_files();
8212     create_database(msifile, aup4_tables, sizeof(aup4_tables) / sizeof(msi_table));
8213
8214     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8215
8216     /* ALLUSERS property set to 2, conditioned on ALLUSERS = 1 */
8217     r = MsiInstallProductA(msifile, "FULL=1");
8218     if (r == ERROR_SUCCESS)
8219     {
8220         /* Win9x/WinMe */
8221         win_skip("Win9x and WinMe act differently with respect to ALLUSERS\n");
8222
8223         ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8224         ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
8225         ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8226         ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
8227         ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8228         ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
8229         ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8230         ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
8231         ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8232         ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8233         ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8234         ok(delete_pf("msitest", FALSE), "File not installed\n");
8235
8236         r = MsiInstallProductA(msifile, "REMOVE=ALL");
8237         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8238
8239         delete_test_files();
8240     }
8241     else
8242         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8243 }
8244
8245 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
8246 static char rename_ops[]      = "PendingFileRenameOperations";
8247
8248 static void process_pending_renames(HKEY hkey)
8249 {
8250     char *buf, *src, *dst, *buf2, *buf2ptr;
8251     DWORD size, buf2len = 0;
8252     LONG ret;
8253     BOOL found = FALSE;
8254
8255     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
8256     buf = HeapAlloc(GetProcessHeap(), 0, size);
8257     buf2ptr = buf2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
8258     buf[0] = 0;
8259
8260     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
8261     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
8262
8263     for (src = buf; *src; src = dst + strlen(dst) + 1)
8264     {
8265         DWORD flags = MOVEFILE_COPY_ALLOWED;
8266
8267         dst = src + strlen(src) + 1;
8268
8269         if (!strstr(src, "msitest"))
8270         {
8271             lstrcpyA(buf2ptr, src);
8272             buf2len += strlen(src) + 1;
8273             buf2ptr += strlen(src) + 1;
8274             if (*dst)
8275             {
8276                 lstrcpyA(buf2ptr, dst);
8277                 buf2ptr += strlen(dst) + 1;
8278                 buf2len += strlen(dst) + 1;
8279             }
8280             buf2ptr++;
8281             buf2len++;
8282             continue;
8283         }
8284
8285         found = TRUE;
8286
8287         if (*dst == '!')
8288         {
8289             flags |= MOVEFILE_REPLACE_EXISTING;
8290             dst++;
8291         }
8292         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
8293         if (*dst)
8294         {
8295             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
8296             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
8297         }
8298         else
8299             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
8300     }
8301
8302     ok(found, "Expected a 'msitest' entry\n");
8303
8304     if (*buf2)
8305     {
8306         buf2len++;
8307         RegSetValueExA(hkey, rename_ops, 0, REG_MULTI_SZ, (LPBYTE)buf2, buf2len);
8308     }
8309     else
8310         RegDeleteValueA(hkey, rename_ops);
8311
8312     HeapFree(GetProcessHeap(), 0, buf);
8313     HeapFree(GetProcessHeap(), 0, buf2);
8314 }
8315
8316 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
8317 {
8318     DWORD len, data_len = strlen(data);
8319     HANDLE handle;
8320     char buf[128];
8321
8322     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
8323     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
8324
8325     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
8326     {
8327         CloseHandle(handle);
8328         return !memcmp(buf, data, data_len);
8329     }
8330     CloseHandle(handle);
8331     return FALSE;
8332 }
8333
8334 static void test_file_in_use(void)
8335 {
8336     UINT r;
8337     HANDLE file;
8338     HKEY hkey;
8339     char path[MAX_PATH];
8340
8341     if (on_win9x)
8342     {
8343         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
8344         return;
8345     }
8346
8347     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
8348
8349     CreateDirectoryA("msitest", NULL);
8350     create_file("msitest\\maximus", 500);
8351     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
8352
8353     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8354
8355     lstrcpy(path, PROG_FILES_DIR);
8356     lstrcat(path, "\\msitest");
8357     CreateDirectoryA(path, NULL);
8358
8359     lstrcat(path, "\\maximus");
8360     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8361
8362     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8363     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8364     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8365     CloseHandle(file);
8366     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
8367
8368     process_pending_renames(hkey);
8369     RegCloseKey(hkey);
8370
8371     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
8372     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8373     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8374
8375     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8377
8378     DeleteFileA("msitest\\maximus");
8379     delete_test_files();
8380 }
8381
8382 static void test_file_in_use_cab(void)
8383 {
8384     UINT r;
8385     HANDLE file;
8386     HKEY hkey;
8387     char path[MAX_PATH];
8388
8389     if (on_win9x)
8390     {
8391         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
8392         return;
8393     }
8394
8395     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
8396
8397     CreateDirectoryA("msitest", NULL);
8398     create_file("maximus", 500);
8399     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
8400     DeleteFile("maximus");
8401
8402     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
8403
8404     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8405
8406     lstrcpy(path, PROG_FILES_DIR);
8407     lstrcat(path, "\\msitest");
8408     CreateDirectoryA(path, NULL);
8409
8410     lstrcat(path, "\\maximus");
8411     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
8412
8413     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
8414     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
8415     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8416     CloseHandle(file);
8417     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
8418
8419     process_pending_renames(hkey);
8420     RegCloseKey(hkey);
8421
8422     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
8423     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
8424     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
8425
8426     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8428
8429     delete_cab_files();
8430     delete_test_files();
8431 }
8432
8433 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
8434 {
8435     return IDOK;
8436 }
8437
8438 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
8439 {
8440     return IDOK;
8441 }
8442
8443 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
8444 {
8445     return IDOK;
8446 }
8447
8448 static void test_MsiSetExternalUI(void)
8449 {
8450     INSTALLUI_HANDLERA ret_a;
8451     INSTALLUI_HANDLERW ret_w;
8452     INSTALLUI_HANDLER_RECORD prev;
8453     UINT error;
8454
8455     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8456     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8457
8458     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8459     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
8460
8461     /* Not present before Installer 3.1 */
8462     if (!pMsiSetExternalUIRecord) {
8463         win_skip("MsiSetExternalUIRecord is not available\n");
8464         return;
8465     }
8466
8467     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8468     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8469     ok(prev == NULL, "expected NULL, got %p\n", prev);
8470
8471     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8472     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
8473     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8474     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8475
8476     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8477     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8478
8479     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8480     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
8481
8482     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
8483     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8484
8485     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
8486     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8487
8488     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8489     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
8490     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8491     ok(prev == NULL, "expected NULL, got %p\n", prev);
8492
8493     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
8494     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
8495
8496     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
8497     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
8498
8499     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
8500     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
8501     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8502     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
8503
8504     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
8505     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8506
8507     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
8508     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
8509 }
8510
8511 static void test_feature_override(void)
8512 {
8513     UINT r;
8514
8515     create_test_files();
8516     create_file("msitest\\override.txt", 1000);
8517     create_file("msitest\\preselected.txt", 1000);
8518     create_file("msitest\\notpreselected.txt", 1000);
8519     create_database(msifile, fo_tables, sizeof(fo_tables) / sizeof(msi_table));
8520
8521     r = MsiInstallProductA(msifile, "ADDLOCAL=override");
8522     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8523
8524     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
8525     ok(!pf_exists("msitest\\preselected.txt"), "file installed\n");
8526     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
8527
8528     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8530
8531     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
8532
8533     r = MsiInstallProductA(msifile, "preselect=1");
8534     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8535
8536     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
8537     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
8538     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
8539
8540     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8542
8543     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
8544     todo_wine {
8545     ok(delete_pf("msitest\\preselected.txt", TRUE), "file removed\n");
8546     ok(delete_pf("msitest", FALSE), "directory removed\n");
8547     }
8548
8549     r = MsiInstallProductA(msifile, NULL);
8550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8551
8552     ok(pf_exists("msitest\\override.txt"), "file not installed\n");
8553     ok(pf_exists("msitest\\preselected.txt"), "file not installed\n");
8554     ok(!pf_exists("msitest\\notpreselected.txt"), "file installed\n");
8555
8556     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8557     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8558
8559     ok(!delete_pf("msitest\\override.txt", TRUE), "file not removed\n");
8560     todo_wine {
8561     ok(delete_pf("msitest\\preselected.txt", TRUE), "file removed\n");
8562     ok(delete_pf("msitest", FALSE), "directory removed\n");
8563     }
8564
8565     DeleteFileA("msitest\\override.txt");
8566     DeleteFileA("msitest\\preselected.txt");
8567     DeleteFileA("msitest\\notpreselected.txt");
8568     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\msitest");
8569     delete_test_files();
8570 }
8571
8572 static void test_create_folder(void)
8573 {
8574     UINT r;
8575
8576     create_test_files();
8577     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
8578
8579     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8580
8581     r = MsiInstallProductA(msifile, NULL);
8582     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8583
8584     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8585     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8586     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8587     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8588     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8589     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8590     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8591     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8592     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8593     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8594     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8595     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8596
8597     r = MsiInstallProductA(msifile, "LOCAL=Two");
8598     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8599
8600     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8601     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8602     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8603     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8604     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8605     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8606     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8607     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8608     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8609     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8610     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8611     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8612
8613     delete_test_files();
8614 }
8615
8616 static void test_remove_folder(void)
8617 {
8618     UINT r;
8619
8620     create_test_files();
8621     create_database(msifile, rf_tables, sizeof(rf_tables) / sizeof(msi_table));
8622
8623     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8624
8625     r = MsiInstallProductA(msifile, NULL);
8626     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8627
8628     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8629     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8630     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8631     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8632     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8633     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8634     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8635     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8636     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8637     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8638     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8639     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8640
8641     r = MsiInstallProductA(msifile, "LOCAL=Two");
8642     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8643
8644     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
8645     ok(!delete_pf("msitest\\cabout\\new", FALSE), "Directory created\n");
8646     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
8647     ok(!delete_pf("msitest\\cabout", FALSE), "Directory created\n");
8648     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
8649     ok(!delete_pf("msitest\\changed", FALSE), "Directory created\n");
8650     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
8651     ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
8652     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
8653     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
8654     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
8655     ok(!delete_pf("msitest", FALSE), "Directory created\n");
8656
8657     delete_test_files();
8658 }
8659
8660 static void test_start_services(void)
8661 {
8662     UINT r;
8663     SC_HANDLE scm, service;
8664     BOOL ret;
8665     DWORD error = ERROR_SUCCESS;
8666
8667     if (on_win9x)
8668     {
8669         win_skip("Services are not implemented on Win9x and WinMe\n");
8670         return;
8671     }
8672     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8673     ok(scm != NULL, "Failed to open the SC Manager\n");
8674     if (!scm) return;
8675
8676     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8677     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
8678     {
8679         win_skip("The 'Spooler' service does not exist\n");
8680         CloseServiceHandle(scm);
8681         return;
8682     }
8683     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
8684     if (!service) {
8685         CloseServiceHandle(scm);
8686         return;
8687     }
8688
8689     ret = StartService(service, 0, NULL);
8690     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
8691     {
8692         skip("Terminal service not available, skipping test\n");
8693         CloseServiceHandle(service);
8694         CloseServiceHandle(scm);
8695         return;
8696     }
8697
8698     CloseServiceHandle(service);
8699     CloseServiceHandle(scm);
8700
8701     create_test_files();
8702     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
8703
8704     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8705
8706     r = MsiInstallProductA(msifile, NULL);
8707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8708
8709     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8710     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8711     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8712     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8713     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8714     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8715     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8716     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8717     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8718     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8719     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8720     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8721
8722     delete_test_files();
8723
8724     if (error == ERROR_SUCCESS)
8725     {
8726         SERVICE_STATUS status;
8727
8728         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8729         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
8730
8731         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
8732         ok(ret, "ControlService failed %u\n", GetLastError());
8733
8734         CloseServiceHandle(service);
8735         CloseServiceHandle(scm);
8736     }
8737 }
8738
8739 static void test_delete_services(void)
8740 {
8741     UINT r;
8742
8743     create_test_files();
8744     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
8745
8746     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8747
8748     r = MsiInstallProductA(msifile, NULL);
8749     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8750
8751     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8752     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8753     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8754     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8755     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8756     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8757     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8758     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8759     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8760     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8761     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8762     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8763
8764     delete_test_files();
8765 }
8766
8767 static void test_self_registration(void)
8768 {
8769     UINT r;
8770
8771     create_test_files();
8772     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
8773
8774     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8775
8776     r = MsiInstallProductA(msifile, NULL);
8777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8778
8779     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8780     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8781     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8782     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8783     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8784     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8785     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8786     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8787     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8788     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8789     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8790     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8791
8792     delete_test_files();
8793 }
8794
8795 static void test_register_font(void)
8796 {
8797     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
8798     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
8799     LONG ret;
8800     HKEY key;
8801     UINT r;
8802
8803     create_test_files();
8804     create_file("msitest\\font.ttf", 1000);
8805     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
8806
8807     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8808
8809     r = MsiInstallProductA(msifile, NULL);
8810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8811
8812     ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont1, &key);
8813     if (ret)
8814         RegOpenKeyA(HKEY_LOCAL_MACHINE, regfont2, &key);
8815
8816     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8817     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8818
8819     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8821
8822     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8823
8824     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
8825     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
8826
8827     RegDeleteValueA(key, "msi test font");
8828     RegCloseKey(key);
8829     DeleteFileA("msitest\\font.ttf");
8830     delete_test_files();
8831 }
8832
8833 static void test_validate_product_id(void)
8834 {
8835     UINT r;
8836
8837     create_test_files();
8838     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
8839
8840     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8841
8842     r = MsiInstallProductA(msifile, NULL);
8843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8844
8845     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
8846     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8847
8848     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
8849     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8850
8851     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
8852     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8853
8854     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
8855     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
8856     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
8857     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
8858     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
8859     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
8860     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
8861     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
8862     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
8863     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
8864     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
8865     ok(delete_pf("msitest", FALSE), "Directory not created\n");
8866
8867     delete_test_files();
8868 }
8869
8870 static void test_install_remove_odbc(void)
8871 {
8872     UINT r;
8873
8874     create_test_files();
8875     create_file("msitest\\ODBCdriver.dll", 1000);
8876     create_file("msitest\\ODBCdriver2.dll", 1000);
8877     create_file("msitest\\ODBCtranslator.dll", 1000);
8878     create_file("msitest\\ODBCtranslator2.dll", 1000);
8879     create_file("msitest\\ODBCsetup.dll", 1000);
8880     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
8881
8882     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8883
8884     r = MsiInstallProductA(msifile, NULL);
8885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8886
8887     ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n");
8888     ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n");
8889     ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n");
8890     ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n");
8891     ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n");
8892
8893     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8895
8896     ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n");
8897     ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n");
8898     ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n");
8899     ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n");
8900     ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n");
8901     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8902
8903     DeleteFileA("msitest\\ODBCdriver.dll");
8904     DeleteFileA("msitest\\ODBCdriver2.dll");
8905     DeleteFileA("msitest\\ODBCtranslator.dll");
8906     DeleteFileA("msitest\\ODBCtranslator2.dll");
8907     DeleteFileA("msitest\\ODBCsetup.dll");
8908     delete_test_files();
8909 }
8910
8911 static void test_register_typelib(void)
8912 {
8913     UINT r;
8914
8915     create_test_files();
8916     create_file("msitest\\typelib.dll", 1000);
8917     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
8918
8919     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8920
8921     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
8922     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
8923
8924     r = MsiInstallProductA(msifile, NULL);
8925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8926
8927     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8929
8930     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
8931     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8932
8933     DeleteFileA("msitest\\typelib.dll");
8934     delete_test_files();
8935 }
8936
8937 static void test_create_remove_shortcut(void)
8938 {
8939     UINT r;
8940
8941     create_test_files();
8942     create_file("msitest\\target.txt", 1000);
8943     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
8944
8945     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8946
8947     r = MsiInstallProductA(msifile, NULL);
8948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8949
8950     ok(pf_exists("msitest\\target.txt"), "file not created\n");
8951     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
8952
8953     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8954     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8955
8956     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
8957     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
8958     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8959
8960     DeleteFileA("msitest\\target.txt");
8961     delete_test_files();
8962 }
8963
8964 static void test_publish_components(void)
8965 {
8966     static char keypath[] =
8967         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
8968
8969     UINT r;
8970     LONG res;
8971     HKEY key;
8972
8973     create_test_files();
8974     create_file("msitest\\english.txt", 1000);
8975     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
8976
8977     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8978
8979     r = MsiInstallProductA(msifile, NULL);
8980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8981
8982     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8983     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
8984
8985     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
8986     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
8987     RegCloseKey(key);
8988
8989     r = MsiInstallProductA(msifile, "REMOVE=ALL");
8990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
8991
8992     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
8993     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
8994
8995     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
8996     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
8997
8998     DeleteFileA("msitest\\english.txt");
8999     delete_test_files();
9000 }
9001
9002 static void test_remove_duplicate_files(void)
9003 {
9004     UINT r;
9005
9006     create_test_files();
9007     create_file("msitest\\original.txt", 1000);
9008     create_file("msitest\\original2.txt", 1000);
9009     create_file("msitest\\original3.txt", 1000);
9010     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
9011
9012     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9013
9014     r = MsiInstallProductA(msifile, NULL);
9015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9016
9017     ok(pf_exists("msitest\\original.txt"), "file not created\n");
9018     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
9019     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
9020     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
9021     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
9022
9023     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9025
9026     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
9027     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
9028     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
9029     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
9030     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
9031     ok(delete_pf("msitest", FALSE), "directory removed\n");
9032
9033     DeleteFileA("msitest\\original.txt");
9034     DeleteFileA("msitest\\original2.txt");
9035     DeleteFileA("msitest\\original3.txt");
9036     delete_test_files();
9037 }
9038
9039 static void test_remove_registry_values(void)
9040 {
9041     UINT r;
9042     LONG res;
9043     HKEY key;
9044
9045     create_test_files();
9046     create_file("msitest\\registry.txt", 1000);
9047     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
9048
9049     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9050
9051     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
9052     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
9053     RegCloseKey(key);
9054
9055     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9056     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
9057     RegCloseKey(key);
9058
9059     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
9060     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
9061     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
9062     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
9063     RegCloseKey(key);
9064
9065     RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
9066     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
9067     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
9068     RegCloseKey(key);
9069
9070     r = MsiInstallProductA(msifile, NULL);
9071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9072
9073     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
9074     ok(res == ERROR_SUCCESS, "key removed\n");
9075     RegCloseKey(key);
9076
9077     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9078     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9079
9080     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9082     RegCloseKey(key);
9083
9084     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9085     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9086
9087     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", &key);
9088     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9089
9090     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", &key);
9091     ok(res == ERROR_SUCCESS, "key removed\n");
9092     RegCloseKey(key);
9093
9094     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", &key);
9095     ok(res == ERROR_SUCCESS, "key removed\n");
9096     RegCloseKey(key);
9097
9098     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", &key);
9099     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9100
9101     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA");
9102     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2");
9103     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine");
9104
9105     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
9106     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9107
9108     DeleteFileA("msitest\\registry.txt");
9109     delete_test_files();
9110 }
9111
9112 static void test_find_related_products(void)
9113 {
9114     UINT r;
9115
9116     create_test_files();
9117     create_file("msitest\\product.txt", 1000);
9118     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
9119
9120     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9121
9122     r = MsiInstallProductA(msifile, NULL);
9123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9124
9125     /* install again, so it finds the upgrade code */
9126     r = MsiInstallProductA(msifile, NULL);
9127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9128
9129     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9131
9132     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
9133     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9134
9135     DeleteFileA("msitest\\product.txt");
9136     delete_test_files();
9137 }
9138
9139 static void test_remove_ini_values(void)
9140 {
9141     UINT r;
9142     DWORD len;
9143     char inifile[MAX_PATH], buf[0x10];
9144     HANDLE file;
9145     BOOL ret;
9146
9147     create_test_files();
9148     create_file("msitest\\inifile.txt", 1000);
9149     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
9150
9151     lstrcpyA(inifile, PROG_FILES_DIR);
9152     lstrcatA(inifile, "\\msitest");
9153     CreateDirectoryA(inifile, NULL);
9154     lstrcatA(inifile, "\\test.ini");
9155     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
9156     CloseHandle(file);
9157
9158     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
9159     ok(ret, "failed to write profile string %u\n", GetLastError());
9160
9161     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
9162     ok(ret, "failed to write profile string %u\n", GetLastError());
9163
9164     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9165
9166     r = MsiInstallProductA(msifile, NULL);
9167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9168
9169     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
9170     ok(len == 6, "got %u expected 6\n", len);
9171
9172     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
9173     ok(!len, "got %u expected 0\n", len);
9174
9175     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9177
9178     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
9179     ok(!len, "got %u expected 0\n", len);
9180
9181     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
9182     ok(!len, "got %u expected 0\n", len);
9183
9184     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
9185     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
9186     ok(delete_pf("msitest", FALSE), "directory removed\n");
9187
9188     DeleteFileA("msitest\\inifile.txt");
9189     delete_test_files();
9190 }
9191
9192 static void test_remove_env_strings(void)
9193 {
9194     UINT r;
9195     LONG res;
9196     HKEY key;
9197     DWORD type, size;
9198     char buffer[0x10];
9199
9200     if (on_win9x)
9201     {
9202         win_skip("Environment variables are handled differently on win9x and winme\n");
9203         return;
9204     }
9205
9206     create_test_files();
9207     create_file("msitest\\envvar.txt", 1000);
9208     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
9209
9210     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9211
9212     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
9213     ok(!res, "failed to open environment key %d\n", res);
9214
9215     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
9216     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
9217     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
9218     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
9219     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
9220
9221     RegCloseKey(key);
9222
9223     r = MsiInstallProductA(msifile, NULL);
9224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9225
9226     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
9227     ok(!res, "failed to open environment key %d\n", res);
9228
9229     type = REG_NONE;
9230     buffer[0] = 0;
9231     size = sizeof(buffer);
9232     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
9233     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9234     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9235     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9236
9237     type = REG_NONE;
9238     buffer[0] = 0;
9239     size = sizeof(buffer);
9240     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
9241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9242     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9243     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9244
9245     type = REG_NONE;
9246     buffer[0] = 0;
9247     size = sizeof(buffer);
9248     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
9249     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9250     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9251     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9252
9253     type = REG_NONE;
9254     buffer[0] = 0;
9255     size = sizeof(buffer);
9256     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
9257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9258     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9259     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9260
9261     type = REG_NONE;
9262     buffer[0] = 0;
9263     size = sizeof(buffer);
9264     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
9265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9266     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9267     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9268
9269     RegCloseKey(key);
9270
9271     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9272     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9273
9274     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
9275     ok(!res, "failed to open environment key %d\n", res);
9276
9277     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
9278     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9279
9280     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
9281     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9282
9283     type = REG_NONE;
9284     buffer[0] = 0;
9285     size = sizeof(buffer);
9286     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
9287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9288     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9289     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9290     RegDeleteValueA(key, "MSITESTVAR3");
9291
9292     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
9293     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
9294
9295     type = REG_NONE;
9296     buffer[0] = 0;
9297     size = sizeof(buffer);
9298     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
9299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9300     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
9301     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
9302     RegDeleteValueA(key, "MSITESTVAR5");
9303
9304     RegCloseKey(key);
9305
9306     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
9307     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9308
9309     DeleteFileA("msitest\\envvar.txt");
9310     delete_test_files();
9311 }
9312
9313 static void test_register_class_info(void)
9314 {
9315     UINT r;
9316     LONG res;
9317     HKEY hkey;
9318
9319     create_test_files();
9320     create_file("msitest\\class.txt", 1000);
9321     create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table));
9322
9323     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9324
9325     r = MsiInstallProductA(msifile, NULL);
9326     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9327
9328     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9329     ok(res == ERROR_SUCCESS, "key not created\n");
9330     RegCloseKey(hkey);
9331
9332     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9333     ok(res == ERROR_SUCCESS, "key not created\n");
9334     RegCloseKey(hkey);
9335
9336     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
9337     ok(res == ERROR_SUCCESS, "key not created\n");
9338     RegCloseKey(hkey);
9339
9340     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9341     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9342
9343     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9344     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9345
9346     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
9347     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9348
9349     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
9350     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9351
9352     ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n");
9353     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9354
9355     DeleteFileA("msitest\\class.txt");
9356     delete_test_files();
9357 }
9358
9359 static void test_register_extension_info(void)
9360 {
9361     UINT r;
9362     LONG res;
9363     HKEY hkey;
9364
9365     create_test_files();
9366     create_file("msitest\\extension.txt", 1000);
9367     create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table));
9368
9369     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9370
9371     r = MsiInstallProductA(msifile, NULL);
9372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9373
9374     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
9375     ok(res == ERROR_SUCCESS, "key not created\n");
9376     RegCloseKey(hkey);
9377
9378     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey);
9379     ok(res == ERROR_SUCCESS, "key not created\n");
9380     RegCloseKey(hkey);
9381
9382     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9384
9385     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
9386     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9387
9388     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey);
9389     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9390
9391     ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n");
9392     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9393
9394     DeleteFileA("msitest\\extension.txt");
9395     delete_test_files();
9396 }
9397
9398 static void test_register_mime_info(void)
9399 {
9400     UINT r;
9401     LONG res;
9402     HKEY hkey;
9403
9404     create_test_files();
9405     create_file("msitest\\mime.txt", 1000);
9406     create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table));
9407
9408     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9409
9410     r = MsiInstallProductA(msifile, NULL);
9411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9412
9413     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
9414     ok(res == ERROR_SUCCESS, "key not created\n");
9415     RegCloseKey(hkey);
9416
9417     r = MsiInstallProductA(msifile, "REMOVE=ALL");
9418     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
9419
9420     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
9421     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
9422
9423     ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n");
9424     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
9425
9426     DeleteFileA("msitest\\mime.txt");
9427     delete_test_files();
9428 }
9429
9430 static void test_icon_table(void)
9431 {
9432     MSIHANDLE hdb = 0, record;
9433     LPCSTR query;
9434     UINT res;
9435     CHAR path[MAX_PATH], win9xpath[MAX_PATH];
9436     static const char prodcode[] = "{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}";
9437
9438     create_database(msifile, icon_base_tables, sizeof(icon_base_tables) / sizeof(msi_table));
9439
9440     res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb);
9441     ok(res == ERROR_SUCCESS, "failed to open db: %d\n", res);
9442
9443     query = "CREATE TABLE `Icon` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL  PRIMARY KEY `Name`)";
9444     res = run_query( hdb, 0, query );
9445     ok(res == ERROR_SUCCESS, "Can't create Icon table: %d\n", res);
9446
9447     create_file("icon.ico", 100);
9448     record = MsiCreateRecord(1);
9449     res = MsiRecordSetStream(record, 1, "icon.ico");
9450     ok(res == ERROR_SUCCESS, "Failed to add stream data to record: %d\n", res);
9451     DeleteFile("icon.ico");
9452
9453     query = "INSERT INTO `Icon` (`Name`, `Data`) VALUES ('testicon', ?)";
9454     res = run_query(hdb, record, query);
9455     ok(res == ERROR_SUCCESS, "Insert into Icon table failed: %d\n", res);
9456
9457     res = MsiCloseHandle(record);
9458     ok(res == ERROR_SUCCESS, "Failed to close record handle: %d\n", res);
9459     res = MsiDatabaseCommit(hdb);
9460     ok(res == ERROR_SUCCESS, "Failed to commit database: %d\n", res);
9461     res = MsiCloseHandle(hdb);
9462     ok(res == ERROR_SUCCESS, "Failed to close database: %d\n", res);
9463
9464     /* per-user */
9465     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
9466     ok(res == ERROR_SUCCESS, "Failed to do per-user install: %d\n", res);
9467
9468     lstrcpyA(path, APP_DATA_DIR);
9469     lstrcatA(path, "\\");
9470     lstrcatA(path, "Microsoft\\Installer\\");
9471     lstrcatA(path, prodcode);
9472     lstrcatA(path, "\\testicon");
9473     ok(file_exists(path), "Per-user icon file isn't where it's expected (%s)\n", path);
9474
9475     res = MsiInstallProductA(msifile, "REMOVE=ALL");
9476     ok(res == ERROR_SUCCESS, "Failed to uninstall per-user\n");
9477
9478     /* system-wide */
9479     res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
9480     ok(res == ERROR_SUCCESS, "Failed to system-wide install: %d\n", res);
9481
9482     /* win9x with MSI 2.0 installs the icon to a different folder, same as above */
9483     lstrcpyA(win9xpath, APP_DATA_DIR);
9484     lstrcatA(path, "\\");
9485     lstrcatA(path, "Microsoft\\Installer\\");
9486     lstrcatA(path, prodcode);
9487     lstrcatA(path, "\\testicon");
9488
9489     lstrcpyA(path, WINDOWS_DIR);
9490     lstrcatA(path, "\\");
9491     lstrcatA(path, "Installer\\");
9492     lstrcatA(path, prodcode);
9493     lstrcatA(path, "\\testicon");
9494     ok(file_exists(path) || file_exists(win9xpath),
9495             "System-wide icon file isn't where it's expected (%s)\n", path);
9496
9497     res = MsiInstallProductA(msifile, "REMOVE=ALL");
9498     ok(res == ERROR_SUCCESS, "Failed to uninstall system-wide\n");
9499
9500     delete_pfmsitest_files();
9501
9502     DeleteFile(msifile);
9503 }
9504
9505 START_TEST(install)
9506 {
9507     DWORD len;
9508     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
9509     STATEMGRSTATUS status;
9510     BOOL ret = FALSE;
9511
9512     init_functionpointers();
9513
9514     on_win9x = check_win9x();
9515
9516     GetCurrentDirectoryA(MAX_PATH, prev_path);
9517     GetTempPath(MAX_PATH, temp_path);
9518     SetCurrentDirectoryA(temp_path);
9519
9520     lstrcpyA(CURR_DIR, temp_path);
9521     len = lstrlenA(CURR_DIR);
9522
9523     if(len && (CURR_DIR[len - 1] == '\\'))
9524         CURR_DIR[len - 1] = 0;
9525
9526     get_system_dirs();
9527     get_user_dirs();
9528
9529     /* Create a restore point ourselves so we circumvent the multitude of restore points
9530      * that would have been created by all the installation and removal tests.
9531      */
9532     if (pSRSetRestorePointA)
9533     {
9534         memset(&status, 0, sizeof(status));
9535         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
9536     }
9537
9538     /* Create only one log file and don't append. We have to pass something
9539      * for the log mode for this to work. The logfile needs to have an absolute
9540      * path otherwise we still end up with some extra logfiles as some tests
9541      * change the current directory.
9542      */
9543     lstrcpyA(log_file, temp_path);
9544     lstrcatA(log_file, "\\msitest.log");
9545     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
9546
9547     test_MsiInstallProduct();
9548     test_MsiSetComponentState();
9549     test_packagecoltypes();
9550     test_continuouscabs();
9551     test_caborder();
9552     test_mixedmedia();
9553     test_samesequence();
9554     test_uiLevelFlags();
9555     test_readonlyfile();
9556     test_readonlyfile_cab();
9557     test_setdirproperty();
9558     test_cabisextracted();
9559     test_concurrentinstall();
9560     test_setpropertyfolder();
9561     test_publish_registerproduct();
9562     test_publish_publishproduct();
9563     test_publish_publishfeatures();
9564     test_publish_registeruser();
9565     test_publish_processcomponents();
9566     test_publish();
9567     test_publishsourcelist();
9568     test_transformprop();
9569     test_currentworkingdir();
9570     test_admin();
9571     test_adminprops();
9572     test_removefiles();
9573     test_movefiles();
9574     test_missingcab();
9575     test_duplicatefiles();
9576     test_writeregistryvalues();
9577     test_sourcefolder();
9578     test_customaction51();
9579     test_installstate();
9580     test_sourcepath();
9581     test_MsiConfigureProductEx();
9582     test_missingcomponent();
9583     test_sourcedirprop();
9584     test_adminimage();
9585     test_propcase();
9586     test_int_widths();
9587     test_shortcut();
9588     test_envvar();
9589     test_lastusedsource();
9590     test_preselected();
9591     test_installed_prop();
9592     test_file_in_use();
9593     test_file_in_use_cab();
9594     test_MsiSetExternalUI();
9595     test_allusers_prop();
9596     test_feature_override();
9597     test_create_folder();
9598     test_remove_folder();
9599     test_start_services();
9600     test_delete_services();
9601     test_self_registration();
9602     test_register_font();
9603     test_validate_product_id();
9604     test_install_remove_odbc();
9605     test_register_typelib();
9606     test_create_remove_shortcut();
9607     test_publish_components();
9608     test_remove_duplicate_files();
9609     test_remove_registry_values();
9610     test_find_related_products();
9611     test_remove_ini_values();
9612     test_remove_env_strings();
9613     test_register_class_info();
9614     test_register_extension_info();
9615     test_register_mime_info();
9616     test_icon_table();
9617
9618     DeleteFileA(log_file);
9619
9620     if (pSRSetRestorePointA && ret)
9621     {
9622         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
9623         if (ret)
9624             remove_restore_point(status.llSequenceNumber);
9625     }
9626     FreeLibrary(hsrclient);
9627
9628     SetCurrentDirectoryA(prev_path);
9629 }