msi: Sign extend the value when converting from a small integer.
[wine] / dlls / msi / tests / install.c
1 /*
2  * Copyright (C) 2006 James Hawkins
3  *
4  * A test program for installing MSI products.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22 #define COBJMACROS
23
24 #include <stdio.h>
25
26 #include <windows.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <msi.h>
30 #include <fci.h>
31 #include <objidl.h>
32 #include <srrestoreptapi.h>
33
34 #include "wine/test.h"
35
36 static UINT (WINAPI *pMsiQueryComponentStateA)
37     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
38 static UINT (WINAPI *pMsiSetExternalUIRecord)
39     (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
40 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiSourceListGetInfoA)
43     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
44
45 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
46
47 static HMODULE hsrclient = 0;
48 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
49 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
50
51 static BOOL on_win9x = FALSE;
52
53 static const char *msifile = "msitest.msi";
54 static const char *msifile2 = "winetest2.msi";
55 static const char *mstfile = "winetest.mst";
56 static CHAR CURR_DIR[MAX_PATH];
57 static CHAR PROG_FILES_DIR[MAX_PATH];
58 static CHAR COMMON_FILES_DIR[MAX_PATH];
59
60 /* msi database data */
61
62 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
63                                     "s72\tS38\ts72\ti2\tS255\tS72\n"
64                                     "Component\tComponent\n"
65                                     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
66                                     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
67                                     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
68                                     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
69                                     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
70                                     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
71                                     "component\t\tMSITESTDIR\t0\t1\tfile\n"
72                                     "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
73
74 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
75                                     "s72\tS72\tl255\n"
76                                     "Directory\tDirectory\n"
77                                     "CABOUTDIR\tMSITESTDIR\tcabout\n"
78                                     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
79                                     "FIRSTDIR\tMSITESTDIR\tfirst\n"
80                                     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
81                                     "NEWDIR\tCABOUTDIR\tnew\n"
82                                     "ProgramFilesFolder\tTARGETDIR\t.\n"
83                                     "TARGETDIR\t\tSourceDir";
84
85 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
86                                   "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
87                                   "Feature\tFeature\n"
88                                   "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
89                                   "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
90                                   "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
91                                   "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
92                                   "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
93                                   "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
94                                   "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
95
96 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
97                                        "s38\ts72\n"
98                                        "FeatureComponents\tFeature_\tComponent_\n"
99                                        "Five\tFive\n"
100                                        "Four\tFour\n"
101                                        "One\tOne\n"
102                                        "Three\tThree\n"
103                                        "Two\tTwo\n"
104                                        "feature\tcomponent\n"
105                                        "service_feature\tservice_comp\n";
106
107 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
108                                "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
109                                "File\tFile\n"
110                                "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
111                                "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
112                                "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
113                                "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
114                                "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
115                                "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
116                                "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
117
118 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
119                                            "s72\tS255\tI2\n"
120                                            "InstallExecuteSequence\tAction\n"
121                                            "AllocateRegistrySpace\tNOT Installed\t1550\n"
122                                            "CostFinalize\t\t1000\n"
123                                            "CostInitialize\t\t800\n"
124                                            "FileCost\t\t900\n"
125                                            "ResolveSource\t\t950\n"
126                                            "MoveFiles\t\t1700\n"
127                                            "InstallFiles\t\t4000\n"
128                                            "DuplicateFiles\t\t4500\n"
129                                            "WriteEnvironmentStrings\t\t4550\n"
130                                            "CreateShortcuts\t\t4600\n"
131                                            "InstallServices\t\t5000\n"
132                                            "InstallFinalize\t\t6600\n"
133                                            "InstallInitialize\t\t1500\n"
134                                            "InstallValidate\t\t1400\n"
135                                            "LaunchConditions\t\t100\n"
136                                            "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
137
138 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
139                                 "i2\ti4\tL64\tS255\tS32\tS72\n"
140                                 "Media\tDiskId\n"
141                                 "1\t3\t\t\tDISK1\t\n"
142                                 "2\t5\t\tmsitest.cab\tDISK2\t\n";
143
144 static const CHAR property_dat[] = "Property\tValue\n"
145                                    "s72\tl0\n"
146                                    "Property\tProperty\n"
147                                    "DefaultUIFont\tDlgFont8\n"
148                                    "HASUIRUN\t0\n"
149                                    "INSTALLLEVEL\t3\n"
150                                    "InstallMode\tTypical\n"
151                                    "Manufacturer\tWine\n"
152                                    "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
153                                    "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
154                                    "ProductID\tnone\n"
155                                    "ProductLanguage\t1033\n"
156                                    "ProductName\tMSITEST\n"
157                                    "ProductVersion\t1.1.1\n"
158                                    "PROMPTROLLBACKCOST\tP\n"
159                                    "Setup\tSetup\n"
160                                    "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
161                                    "AdminProperties\tPOSTADMIN\n"
162                                    "ROOTDRIVE\tC:\\\n"
163                                    "SERVNAME\tTestService\n"
164                                    "SERVDISP\tTestServiceDisp\n";
165
166 static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
167                                    "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
168                                    "Shortcut\tShortcut\n"
169                                    "Shortcut\tMSITESTDIR\tShortcut\tcomponent\tShortcut\t\tShortcut\t\t\t\t\t\n";
170
171 static const CHAR environment_dat[] = "Environment\tName\tValue\tComponent_\n"
172                                       "s72\tl255\tL255\ts72\n"
173                                       "Environment\tEnvironment\n"
174                                       "Var1\t=-MSITESTVAR1\t1\tOne\n"
175                                       "Var2\tMSITESTVAR2\t1\tOne\n"
176                                       "Var3\t=-MSITESTVAR3\t1\tOne\n"
177                                       "Var4\tMSITESTVAR4\t1\tOne\n"
178                                       "Var5\t-MSITESTVAR5\t\tOne\n"
179                                       "Var6\tMSITESTVAR6\t\tOne\n"
180                                       "Var7\t!-MSITESTVAR7\t\tOne\n"
181                                       "Var8\t!-*MSITESTVAR8\t\tOne\n"
182                                       "Var9\t=-MSITESTVAR9\t\tOne\n"
183                                       "Var10\t=MSITESTVAR10\t\tOne\n";
184
185 static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n"
186                                     "s38\ti2\tS255\n"
187                                     "Condition\tFeature_\tLevel\n"
188                                     "One\t4\t1\n";
189
190 static const CHAR up_property_dat[] = "Property\tValue\n"
191                                       "s72\tl0\n"
192                                       "Property\tProperty\n"
193                                       "DefaultUIFont\tDlgFont8\n"
194                                       "HASUIRUN\t0\n"
195                                       "INSTALLLEVEL\t3\n"
196                                       "InstallMode\tTypical\n"
197                                       "Manufacturer\tWine\n"
198                                       "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
199                                       "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
200                                       "ProductID\tnone\n"
201                                       "ProductLanguage\t1033\n"
202                                       "ProductName\tMSITEST\n"
203                                       "ProductVersion\t1.1.1\n"
204                                       "PROMPTROLLBACKCOST\tP\n"
205                                       "Setup\tSetup\n"
206                                       "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
207                                       "AdminProperties\tPOSTADMIN\n"
208                                       "ROOTDRIVE\tC:\\\n"
209                                       "SERVNAME\tTestService\n"
210                                       "SERVDISP\tTestServiceDisp\n"
211                                       "RemovePreviousVersions\t1\n";
212
213 static const CHAR up2_property_dat[] = "Property\tValue\n"
214                                        "s72\tl0\n"
215                                        "Property\tProperty\n"
216                                        "DefaultUIFont\tDlgFont8\n"
217                                        "HASUIRUN\t0\n"
218                                        "INSTALLLEVEL\t3\n"
219                                        "InstallMode\tTypical\n"
220                                        "Manufacturer\tWine\n"
221                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
222                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
223                                        "ProductID\tnone\n"
224                                        "ProductLanguage\t1033\n"
225                                        "ProductName\tMSITEST\n"
226                                        "ProductVersion\t1.1.2\n"
227                                        "PROMPTROLLBACKCOST\tP\n"
228                                        "Setup\tSetup\n"
229                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
230                                        "AdminProperties\tPOSTADMIN\n"
231                                        "ROOTDRIVE\tC:\\\n"
232                                        "SERVNAME\tTestService\n"
233                                        "SERVDISP\tTestServiceDisp\n";
234
235 static const CHAR up3_property_dat[] = "Property\tValue\n"
236                                        "s72\tl0\n"
237                                        "Property\tProperty\n"
238                                        "DefaultUIFont\tDlgFont8\n"
239                                        "HASUIRUN\t0\n"
240                                        "INSTALLLEVEL\t3\n"
241                                        "InstallMode\tTypical\n"
242                                        "Manufacturer\tWine\n"
243                                        "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
244                                        "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
245                                        "ProductID\tnone\n"
246                                        "ProductLanguage\t1033\n"
247                                        "ProductName\tMSITEST\n"
248                                        "ProductVersion\t1.1.2\n"
249                                        "PROMPTROLLBACKCOST\tP\n"
250                                        "Setup\tSetup\n"
251                                        "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
252                                        "AdminProperties\tPOSTADMIN\n"
253                                        "ROOTDRIVE\tC:\\\n"
254                                        "SERVNAME\tTestService\n"
255                                        "SERVDISP\tTestServiceDisp\n"
256                                        "RemovePreviousVersions\t1\n";
257
258 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
259                                    "s72\ti2\tl255\tL255\tL0\ts72\n"
260                                    "Registry\tRegistry\n"
261                                    "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
262                                    "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
263                                    "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
264                                    "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
265
266 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
267                                           "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
268                                           "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
269                                           "ServiceInstall\tServiceInstall\n"
270                                           "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
271
272 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
273                                           "s72\tl255\ti2\tL255\tI2\ts72\n"
274                                           "ServiceControl\tServiceControl\n"
275                                           "ServiceControl\tTestService\t8\t\t0\tservice_comp";
276
277 /* tables for test_continuouscabs */
278 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
279                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
280                                        "Component\tComponent\n"
281                                        "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
282                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
283                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
284
285 static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
286                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
287                                         "Component\tComponent\n"
288                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
289                                         "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
290                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
291
292 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
293                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
294                                      "Feature\tFeature\n"
295                                      "feature\t\t\t\t2\t1\tTARGETDIR\t0";
296
297 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
298                                           "s38\ts72\n"
299                                           "FeatureComponents\tFeature_\tComponent_\n"
300                                           "feature\tmaximus\n"
301                                           "feature\taugustus\n"
302                                           "feature\tcaesar";
303
304 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
305                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
306                                   "File\tFile\n"
307                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
308                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
309                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
310
311 static const CHAR cc2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
312                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
313                                    "File\tFile\n"
314                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
315                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
316                                    "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
317                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
318
319 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
320                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
321                                    "Media\tDiskId\n"
322                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
323                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
324                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
325
326 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
327                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
328                                   "File\tFile\n"
329                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
330                                   "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
331                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
332
333 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
334                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
335                                    "Media\tDiskId\n"
336                                    "1\t10\t\ttest1.cab\tDISK1\t\n"
337                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
338                                    "3\t3\t\ttest3.cab\tDISK3\t\n";
339
340 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
341                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
342                                     "Media\tDiskId\n"
343                                     "1\t10\t\ttest1.cab\tDISK1\t\n"
344                                     "2\t12\t\ttest3.cab\tDISK3\t\n"
345                                     "3\t2\t\ttest2.cab\tDISK2\t\n";
346
347 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
348                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
349                                   "File\tFile\n"
350                                   "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
351                                   "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
352                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
353
354 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
355                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
356                                    "Media\tDiskId\n"
357                                    "1\t3\t\ttest1.cab\tDISK1\t\n";
358
359 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
360                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
361                                    "Media\tDiskId\n"
362                                    "1\t2\t\ttest1.cab\tDISK1\t\n"
363                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
364                                    "3\t12\t\ttest3.cab\tDISK3\t\n";
365
366 /* tables for test_uiLevelFlags */
367 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
368                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
369                                        "Component\tComponent\n"
370                                        "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
371                                        "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
372                                        "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
373
374 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
375                                            "s72\tS255\tI2\n"
376                                            "InstallUISequence\tAction\n"
377                                            "SetUIProperty\t\t5\n"
378                                            "ExecuteAction\t\t1100\n";
379
380 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
381                                            "s72\ti2\tS64\tS0\tS255\n"
382                                            "CustomAction\tAction\n"
383                                            "SetUIProperty\t51\tHASUIRUN\t1\t\n";
384
385 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
386                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
387                                         "Component\tComponent\n"
388                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
389
390 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
391                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
392                                       "Feature\tFeature\n"
393                                       "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
394                                       "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
395
396 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
397                                            "s38\ts72\n"
398                                            "FeatureComponents\tFeature_\tComponent_\n"
399                                            "feature\tmaximus\n"
400                                            "montecristo\tmaximus";
401
402 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
403                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
404                                    "File\tFile\n"
405                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
406
407 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
408                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
409                                     "Media\tDiskId\n"
410                                     "1\t1\t\t\tDISK1\t\n";
411
412 static const CHAR rofc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
413                                     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
414                                     "File\tFile\n"
415                                     "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1";
416
417 static const CHAR rofc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
418                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
419                                      "Media\tDiskId\n"
420                                      "1\t1\t\ttest1.cab\tDISK1\t\n";
421
422 static const CHAR lus2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
423                                      "i2\ti4\tL64\tS255\tS32\tS72\n"
424                                      "Media\tDiskId\n"
425                                      "1\t1\t\t#test1.cab\tDISK1\t\n";
426
427 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
428                                                "s72\tS255\tI2\n"
429                                                "InstallExecuteSequence\tAction\n"
430                                                "AllocateRegistrySpace\tNOT Installed\t1550\n"
431                                                "CostFinalize\t\t1000\n"
432                                                "CostInitialize\t\t800\n"
433                                                "FileCost\t\t900\n"
434                                                "InstallFiles\t\t4000\n"
435                                                "InstallFinalize\t\t6600\n"
436                                                "InstallInitialize\t\t1500\n"
437                                                "InstallValidate\t\t1400\n"
438                                                "LaunchConditions\t\t100\n"
439                                                "SetDirProperty\t\t950";
440
441 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
442                                             "s72\ti2\tS64\tS0\tS255\n"
443                                             "CustomAction\tAction\n"
444                                             "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
445
446 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
447                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
448                                         "Component\tComponent\n"
449                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
450                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
451                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
452                                         "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
453
454 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
455                                            "s38\ts72\n"
456                                            "FeatureComponents\tFeature_\tComponent_\n"
457                                            "feature\tmaximus\n"
458                                            "feature\taugustus\n"
459                                            "feature\tcaesar\n"
460                                            "feature\tgaius";
461
462 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
463                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
464                                    "File\tFile\n"
465                                    "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
466                                    "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
467                                    "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
468                                    "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
469
470 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
471                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
472                                     "Media\tDiskId\n"
473                                     "1\t1\t\ttest1.cab\tDISK1\t\n"
474                                     "2\t2\t\ttest2.cab\tDISK2\t\n"
475                                     "3\t12\t\ttest3.cab\tDISK3\t\n";
476
477 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
478                                               "s72\tS255\tI2\n"
479                                               "InstallExecuteSequence\tAction\n"
480                                               "CostFinalize\t\t1000\n"
481                                               "CostInitialize\t\t800\n"
482                                               "FileCost\t\t900\n"
483                                               "InstallFiles\t\t4000\n"
484                                               "InstallServices\t\t5000\n"
485                                               "InstallFinalize\t\t6600\n"
486                                               "InstallInitialize\t\t1500\n"
487                                               "RunInstall\t\t1600\n"
488                                               "InstallValidate\t\t1400\n"
489                                               "LaunchConditions\t\t100";
490
491 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
492                                             "s72\ti2\tS64\tS0\tS255\n"
493                                             "CustomAction\tAction\n"
494                                             "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
495
496 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
497                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
498                                        "Component\tComponent\n"
499                                        "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
500
501 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
502                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
503                                         "Component\tComponent\n"
504                                         "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
505
506 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
507                                            "s38\ts72\n"
508                                            "FeatureComponents\tFeature_\tComponent_\n"
509                                            "feature\taugustus";
510
511 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
512                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
513                                    "File\tFile\n"
514                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
515
516 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
517                                             "s72\ti2\tS64\tS0\tS255\n"
518                                             "CustomAction\tAction\n"
519                                             "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
520
521 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
522                                                "s72\tS255\tI2\n"
523                                                "InstallExecuteSequence\tAction\n"
524                                                "CostFinalize\t\t1000\n"
525                                                "CostInitialize\t\t800\n"
526                                                "FileCost\t\t900\n"
527                                                "SetFolderProp\t\t950\n"
528                                                "InstallFiles\t\t4000\n"
529                                                "InstallServices\t\t5000\n"
530                                                "InstallFinalize\t\t6600\n"
531                                                "InstallInitialize\t\t1500\n"
532                                                "InstallValidate\t\t1400\n"
533                                                "LaunchConditions\t\t100";
534
535 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
536                                              "s72\tS255\tI2\n"
537                                              "InstallUISequence\tAction\n"
538                                              "CostInitialize\t\t800\n"
539                                              "FileCost\t\t900\n"
540                                              "CostFinalize\t\t1000\n"
541                                              "ExecuteAction\t\t1100\n";
542
543 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
544                                               "s72\tS255\tI2\n"
545                                               "InstallExecuteSequence\tAction\n"
546                                               "ValidateProductID\t\t700\n"
547                                               "CostInitialize\t\t800\n"
548                                               "FileCost\t\t900\n"
549                                               "CostFinalize\t\t1000\n"
550                                               "InstallValidate\t\t1400\n"
551                                               "InstallInitialize\t\t1500\n"
552                                               "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
553                                               "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
554                                               "RemoveFiles\t\t3500\n"
555                                               "InstallFiles\t\t4000\n"
556                                               "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
557                                               "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
558                                               "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
559                                               "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
560                                               "InstallFinalize\t\t6600";
561
562 static const CHAR ppc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
563                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
564                                         "Component\tComponent\n"
565                                         "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n"
566                                         "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n";
567
568 static const CHAR ppc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
569                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
570                                    "File\tFile\n"
571                                    "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n"
572                                    "augustus\taugustus\taugustus\t500\t\t\t8192\t2";
573
574 static const CHAR ppc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
575                                     "i2\ti4\tL64\tS255\tS32\tS72\n"
576                                     "Media\tDiskId\n"
577                                     "1\t2\t\t\tDISK1\t\n";
578
579 static const CHAR ppc_feature_comp_dat[] = "Feature_\tComponent_\n"
580                                            "s38\ts72\n"
581                                            "FeatureComponents\tFeature_\tComponent_\n"
582                                            "feature\tmaximus\n"
583                                            "feature\taugustus\n"
584                                            "montecristo\tmaximus";
585
586 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
587                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
588                                        "Component\tComponent\n"
589                                        "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
590
591 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
592                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
593                                         "Component\tComponent\n"
594                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
595
596 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
597                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
598                                         "Component\tComponent\n"
599                                         "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
600
601 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
602                                             "s72\ti2\tS64\tS0\tS255\n"
603                                             "CustomAction\tAction\n"
604                                             "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
605
606 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
607                                              "s72\tS255\tI2\n"
608                                              "AdminExecuteSequence\tAction\n"
609                                              "CostFinalize\t\t1000\n"
610                                              "CostInitialize\t\t800\n"
611                                              "FileCost\t\t900\n"
612                                              "SetPOSTADMIN\t\t950\n"
613                                              "InstallFiles\t\t4000\n"
614                                              "InstallFinalize\t\t6600\n"
615                                              "InstallInitialize\t\t1500\n"
616                                              "InstallValidate\t\t1400\n"
617                                              "LaunchConditions\t\t100";
618
619 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
620                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
621                                         "Component\tComponent\n"
622                                         "augustus\t\tMSITESTDIR\t0\tMYPROP=2718 and MyProp=42\taugustus\n";
623
624 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
625                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
626                                         "Component\tComponent\n"
627                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
628                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
629                                         "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
630
631 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
632                                            "s38\ts72\n"
633                                            "FeatureComponents\tFeature_\tComponent_\n"
634                                            "feature\thydrogen\n"
635                                            "feature\thelium\n"
636                                            "feature\tlithium";
637
638 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
639                                    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
640                                    "File\tFile\n"
641                                    "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
642                                    "helium\thelium\thelium\t0\t\t\t8192\t1\n"
643                                    "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
644
645 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
646                                                "s72\tS255\tI2\n"
647                                                "InstallExecuteSequence\tAction\n"
648                                                "ValidateProductID\t\t700\n"
649                                                "CostInitialize\t\t800\n"
650                                                "FileCost\t\t900\n"
651                                                "CostFinalize\t\t1000\n"
652                                                "InstallValidate\t\t1400\n"
653                                                "InstallInitialize\t\t1500\n"
654                                                "ProcessComponents\t\t1600\n"
655                                                "UnpublishFeatures\t\t1800\n"
656                                                "RemoveFiles\t\t3500\n"
657                                                "InstallFiles\t\t4000\n"
658                                                "RegisterProduct\t\t6100\n"
659                                                "PublishFeatures\t\t6300\n"
660                                                "PublishProduct\t\t6400\n"
661                                                "InstallFinalize\t\t6600";
662
663 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
664                                            "s72\ts72\tS255\ts72\tI2\n"
665                                            "RemoveFile\tFileKey\n"
666                                            "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
667                                            "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
668                                            "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
669                                            "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
670                                            "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
671                                            "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
672                                            "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
673                                            "block\thelium\tblock\tMSITESTDIR\t3\n"
674                                            "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n"
675                                            "nanoacre\thydrogen\t\tCABOUTDIR\t3\n";
676
677 static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
678                                         "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
679                                         "MoveFile\tFileKey\n"
680                                         "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
681                                         "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
682                                         "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
683                                         "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
684                                         "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
685                                         "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
686                                         "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
687                                         "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
688                                         "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
689                                         "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
690                                         "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
691                                         "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
692                                         "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
693                                         "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n"
694                                         "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
695                                         "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
696                                         "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
697                                         "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
698
699 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
700                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
701                                         "Component\tComponent\n"
702                                         "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
703                                         "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
704                                         "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
705                                         "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
706
707 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
708                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
709                                   "File\tFile\n"
710                                   "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
711                                   "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
712                                   "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
713                                   "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
714
715 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
716                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
717                                    "Media\tDiskId\n"
718                                    "1\t1\t\ttest1.cab\tDISK1\t\n"
719                                    "2\t2\t\ttest2.cab\tDISK2\t\n"
720                                    "3\t3\t\ttest3.cab\tDISK3\t\n"
721                                    "4\t4\t\ttest3.cab\tDISK3\t\n";
722
723 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
724                                        "s72\ti2\ti4\ti4\ti4\ti4\n"
725                                        "MsiFileHash\tFile_\n"
726                                        "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
727
728 static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
729                                        "s72\tS72\tl255\n"
730                                        "Directory\tDirectory\n"
731                                        "THIS\tMSITESTDIR\tthis\n"
732                                        "DOESNOT\tTHIS\tdoesnot\n"
733                                        "NONEXISTENT\tDOESNOT\texist\n"
734                                        "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
735                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
736                                        "TARGETDIR\t\tSourceDir";
737
738 static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
739                                             "s72\ts72\ts72\tS255\tS72\n"
740                                             "DuplicateFile\tFileKey\n"
741                                             "maximus\tmaximus\tmaximus\taugustus\t\n"
742                                             "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n";
743
744 static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
745                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
746                                         "Component\tComponent\n"
747                                         "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
748
749 static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
750                                        "s72\ti2\tl255\tL255\tL0\ts72\n"
751                                        "Registry\tRegistry\n"
752                                        "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
753
754 static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
755                                          "s72\tS38\ts72\ti2\tS255\tS72\n"
756                                          "Component\tComponent\n"
757                                          "augustus\t\tMSITESTDIR\t0\tMYPROP=42\taugustus\n";
758
759 static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
760                                                 "s72\tS255\tI2\n"
761                                                 "InstallExecuteSequence\tAction\n"
762                                                 "ValidateProductID\t\t700\n"
763                                                 "GoodSetProperty\t\t725\n"
764                                                 "BadSetProperty\t\t750\n"
765                                                 "CostInitialize\t\t800\n"
766                                                 "ResolveSource\t\t810\n"
767                                                 "FileCost\t\t900\n"
768                                                 "SetSourceDir\tSRCDIR\t910\n"
769                                                 "CostFinalize\t\t1000\n"
770                                                 "InstallValidate\t\t1400\n"
771                                                 "InstallInitialize\t\t1500\n"
772                                                 "InstallFiles\t\t4000\n"
773                                                 "InstallFinalize\t\t6600";
774
775 static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
776                                              "s72\ti2\tS64\tS0\n"
777                                              "CustomAction\tAction\n"
778                                              "GoodSetProperty\t51\tMYPROP\t42\n"
779                                              "BadSetProperty\t51\t\tMYPROP\n"
780                                              "SetSourceDir\t51\tSourceDir\t[SRCDIR]\n";
781
782 static const CHAR is_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
783                                      "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
784                                      "Feature\tFeature\n"
785                                      "one\t\t\t\t2\t1\t\t0\n" /* favorLocal */
786                                      "two\t\t\t\t2\t1\t\t1\n" /* favorSource */
787                                      "three\t\t\t\t2\t1\t\t4\n" /* favorAdvertise */
788                                      "four\t\t\t\t2\t0\t\t0"; /* disabled */
789
790 static const CHAR is_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
791                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
792                                        "Component\tComponent\n"
793                                        "alpha\t\tMSITESTDIR\t0\t\talpha_file\n" /* favorLocal:Local */
794                                        "beta\t\tMSITESTDIR\t1\t\tbeta_file\n" /* favorLocal:Source */
795                                        "gamma\t\tMSITESTDIR\t2\t\tgamma_file\n" /* favorLocal:Optional */
796                                        "theta\t\tMSITESTDIR\t0\t\ttheta_file\n" /* favorSource:Local */
797                                        "delta\t\tMSITESTDIR\t1\t\tdelta_file\n" /* favorSource:Source */
798                                        "epsilon\t\tMSITESTDIR\t2\t\tepsilon_file\n" /* favorSource:Optional */
799                                        "zeta\t\tMSITESTDIR\t0\t\tzeta_file\n" /* favorAdvertise:Local */
800                                        "iota\t\tMSITESTDIR\t1\t\tiota_file\n" /* favorAdvertise:Source */
801                                        "eta\t\tMSITESTDIR\t2\t\teta_file\n" /* favorAdvertise:Optional */
802                                        "kappa\t\tMSITESTDIR\t0\t\tkappa_file\n" /* disabled:Local */
803                                        "lambda\t\tMSITESTDIR\t1\t\tlambda_file\n" /* disabled:Source */
804                                        "mu\t\tMSITESTDIR\t2\t\tmu_file\n"; /* disabled:Optional */
805
806 static const CHAR is_feature_comp_dat[] = "Feature_\tComponent_\n"
807                                           "s38\ts72\n"
808                                           "FeatureComponents\tFeature_\tComponent_\n"
809                                           "one\talpha\n"
810                                           "one\tbeta\n"
811                                           "one\tgamma\n"
812                                           "two\ttheta\n"
813                                           "two\tdelta\n"
814                                           "two\tepsilon\n"
815                                           "three\tzeta\n"
816                                           "three\tiota\n"
817                                           "three\teta\n"
818                                           "four\tkappa\n"
819                                           "four\tlambda\n"
820                                           "four\tmu";
821
822 static const CHAR is_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
823                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
824                                   "File\tFile\n"
825                                   "alpha_file\talpha\talpha\t500\t\t\t8192\t1\n"
826                                   "beta_file\tbeta\tbeta\t500\t\t\t8291\t2\n"
827                                   "gamma_file\tgamma\tgamma\t500\t\t\t8192\t3\n"
828                                   "theta_file\ttheta\ttheta\t500\t\t\t8192\t4\n"
829                                   "delta_file\tdelta\tdelta\t500\t\t\t8192\t5\n"
830                                   "epsilon_file\tepsilon\tepsilon\t500\t\t\t8192\t6\n"
831                                   "zeta_file\tzeta\tzeta\t500\t\t\t8192\t7\n"
832                                   "iota_file\tiota\tiota\t500\t\t\t8192\t8\n"
833                                   "eta_file\teta\teta\t500\t\t\t8192\t9\n"
834                                   "kappa_file\tkappa\tkappa\t500\t\t\t8192\t10\n"
835                                   "lambda_file\tlambda\tlambda\t500\t\t\t8192\t11\n"
836                                   "mu_file\tmu\tmu\t500\t\t\t8192\t12";
837
838 static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
839                                    "i2\ti4\tL64\tS255\tS32\tS72\n"
840                                    "Media\tDiskId\n"
841                                    "1\t12\t\t\tDISK1\t\n";
842
843 static const CHAR sp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
844                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
845                                         "Component\tComponent\n"
846                                         "augustus\t\tTWODIR\t0\t\taugustus\n";
847
848 static const CHAR sp_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
849                                        "s72\tS72\tl255\n"
850                                        "Directory\tDirectory\n"
851                                        "TARGETDIR\t\tSourceDir\n"
852                                        "ProgramFilesFolder\tTARGETDIR\t.\n"
853                                        "MSITESTDIR\tProgramFilesFolder\tmsitest:.\n"
854                                        "ONEDIR\tMSITESTDIR\t.:shortone|longone\n"
855                                        "TWODIR\tONEDIR\t.:shorttwo|longtwo";
856
857 static const CHAR mcp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
858                                         "s72\tS38\ts72\ti2\tS255\tS72\n"
859                                         "Component\tComponent\n"
860                                         "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
861                                         "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
862                                         "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
863
864 static const CHAR mcp_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
865                                       "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
866                                       "Feature\tFeature\n"
867                                       "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
868                                       "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
869                                       "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
870
871 static const CHAR mcp_feature_comp_dat[] = "Feature_\tComponent_\n"
872                                            "s38\ts72\n"
873                                            "FeatureComponents\tFeature_\tComponent_\n"
874                                            "hydroxyl\thydrogen\n"
875                                            "heliox\thelium\n"
876                                            "lithia\tlithium";
877
878 static const CHAR mcomp_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
879                                      "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
880                                      "File\tFile\n"
881                                      "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
882                                      "helium\thelium\thelium\t0\t\t\t8192\t1\n"
883                                      "lithium\tlithium\tlithium\t0\t\t\t8192\t1\n"
884                                      "beryllium\tmissingcomp\tberyllium\t0\t\t\t8192\t1";
885
886 static const CHAR ai_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
887                                   "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
888                                   "File\tFile\n"
889                                   "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
890                                   "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
891                                   "one.txt\tOne\tone.txt\t1000\t\t\t16384\t1\n"
892                                   "three.txt\tThree\tthree.txt\t1000\t\t\t16384\t3\n"
893                                   "two.txt\tTwo\ttwo.txt\t1000\t\t\t16384\t2\n"
894                                   "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
895                                   "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
896
897 static const CHAR ip_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
898                                               "s72\tS255\tI2\n"
899                                               "InstallExecuteSequence\tAction\n"
900                                               "CostFinalize\t\t1000\n"
901                                               "ValidateProductID\t\t700\n"
902                                               "CostInitialize\t\t800\n"
903                                               "FileCost\t\t900\n"
904                                               "RemoveFiles\t\t3500\n"
905                                               "InstallFiles\t\t4000\n"
906                                               "RegisterUser\t\t6000\n"
907                                               "RegisterProduct\t\t6100\n"
908                                               "PublishFeatures\t\t6300\n"
909                                               "PublishProduct\t\t6400\n"
910                                               "InstallFinalize\t\t6600\n"
911                                               "InstallInitialize\t\t1500\n"
912                                               "ProcessComponents\t\t1600\n"
913                                               "UnpublishFeatures\t\t1800\n"
914                                               "InstallValidate\t\t1400\n"
915                                               "LaunchConditions\t\t100\n"
916                                               "TestInstalledProp\tInstalled AND NOT REMOVE\t950\n";
917
918 static const CHAR ip_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
919                                            "s72\ti2\tS64\tS0\tS255\n"
920                                            "CustomAction\tAction\n"
921                                            "TestInstalledProp\t19\t\tTest failed\t\n";
922
923 static const CHAR aup_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
924                                                "s72\tS255\tI2\n"
925                                                "InstallExecuteSequence\tAction\n"
926                                                "CostFinalize\t\t1000\n"
927                                                "ValidateProductID\t\t700\n"
928                                                "CostInitialize\t\t800\n"
929                                                "FileCost\t\t900\n"
930                                                "RemoveFiles\t\t3500\n"
931                                                "InstallFiles\t\t4000\n"
932                                                "RegisterUser\t\t6000\n"
933                                                "RegisterProduct\t\t6100\n"
934                                                "PublishFeatures\t\t6300\n"
935                                                "PublishProduct\t\t6400\n"
936                                                "InstallFinalize\t\t6600\n"
937                                                "InstallInitialize\t\t1500\n"
938                                                "ProcessComponents\t\t1600\n"
939                                                "UnpublishFeatures\t\t1800\n"
940                                                "InstallValidate\t\t1400\n"
941                                                "LaunchConditions\t\t100\n"
942                                                "TestAllUsersProp\tALLUSERS AND NOT REMOVE\t50\n";
943
944 static const CHAR aup_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
945                                             "s72\ti2\tS64\tS0\tS255\n"
946                                             "CustomAction\tAction\n"
947                                             "TestAllUsersProp\t19\t\tTest failed\t\n";
948
949 typedef struct _msi_table
950 {
951     const CHAR *filename;
952     const CHAR *data;
953     int size;
954 } msi_table;
955
956 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
957
958 static const msi_table tables[] =
959 {
960     ADD_TABLE(component),
961     ADD_TABLE(directory),
962     ADD_TABLE(feature),
963     ADD_TABLE(feature_comp),
964     ADD_TABLE(file),
965     ADD_TABLE(install_exec_seq),
966     ADD_TABLE(media),
967     ADD_TABLE(property),
968     ADD_TABLE(registry),
969     ADD_TABLE(service_install),
970     ADD_TABLE(service_control)
971 };
972
973 static const msi_table sc_tables[] =
974 {
975     ADD_TABLE(component),
976     ADD_TABLE(directory),
977     ADD_TABLE(feature),
978     ADD_TABLE(feature_comp),
979     ADD_TABLE(file),
980     ADD_TABLE(install_exec_seq),
981     ADD_TABLE(media),
982     ADD_TABLE(property),
983     ADD_TABLE(shortcut)
984 };
985
986 static const msi_table ps_tables[] =
987 {
988     ADD_TABLE(component),
989     ADD_TABLE(directory),
990     ADD_TABLE(feature),
991     ADD_TABLE(feature_comp),
992     ADD_TABLE(file),
993     ADD_TABLE(install_exec_seq),
994     ADD_TABLE(media),
995     ADD_TABLE(property),
996     ADD_TABLE(condition)
997 };
998
999 static const msi_table env_tables[] =
1000 {
1001     ADD_TABLE(component),
1002     ADD_TABLE(directory),
1003     ADD_TABLE(feature),
1004     ADD_TABLE(feature_comp),
1005     ADD_TABLE(file),
1006     ADD_TABLE(install_exec_seq),
1007     ADD_TABLE(media),
1008     ADD_TABLE(property),
1009     ADD_TABLE(environment)
1010 };
1011
1012 static const msi_table up_tables[] =
1013 {
1014     ADD_TABLE(component),
1015     ADD_TABLE(directory),
1016     ADD_TABLE(feature),
1017     ADD_TABLE(feature_comp),
1018     ADD_TABLE(file),
1019     ADD_TABLE(install_exec_seq),
1020     ADD_TABLE(media),
1021     ADD_TABLE(up_property),
1022     ADD_TABLE(registry),
1023     ADD_TABLE(service_install),
1024     ADD_TABLE(service_control)
1025 };
1026
1027 static const msi_table up2_tables[] =
1028 {
1029     ADD_TABLE(component),
1030     ADD_TABLE(directory),
1031     ADD_TABLE(feature),
1032     ADD_TABLE(feature_comp),
1033     ADD_TABLE(file),
1034     ADD_TABLE(install_exec_seq),
1035     ADD_TABLE(media),
1036     ADD_TABLE(up2_property),
1037     ADD_TABLE(registry),
1038     ADD_TABLE(service_install),
1039     ADD_TABLE(service_control)
1040 };
1041
1042 static const msi_table up3_tables[] =
1043 {
1044     ADD_TABLE(component),
1045     ADD_TABLE(directory),
1046     ADD_TABLE(feature),
1047     ADD_TABLE(feature_comp),
1048     ADD_TABLE(file),
1049     ADD_TABLE(install_exec_seq),
1050     ADD_TABLE(media),
1051     ADD_TABLE(up3_property),
1052     ADD_TABLE(registry),
1053     ADD_TABLE(service_install),
1054     ADD_TABLE(service_control)
1055 };
1056
1057 static const msi_table up4_tables[] =
1058 {
1059     ADD_TABLE(component),
1060     ADD_TABLE(directory),
1061     ADD_TABLE(feature),
1062     ADD_TABLE(feature_comp),
1063     ADD_TABLE(file),
1064     ADD_TABLE(pp_install_exec_seq),
1065     ADD_TABLE(media),
1066     ADD_TABLE(property),
1067     ADD_TABLE(registry),
1068     ADD_TABLE(service_install),
1069     ADD_TABLE(service_control)
1070 };
1071
1072 static const msi_table up5_tables[] =
1073 {
1074     ADD_TABLE(component),
1075     ADD_TABLE(directory),
1076     ADD_TABLE(feature),
1077     ADD_TABLE(feature_comp),
1078     ADD_TABLE(file),
1079     ADD_TABLE(pp_install_exec_seq),
1080     ADD_TABLE(media),
1081     ADD_TABLE(up_property),
1082     ADD_TABLE(registry),
1083     ADD_TABLE(service_install),
1084     ADD_TABLE(service_control)
1085 };
1086
1087 static const msi_table up6_tables[] =
1088 {
1089     ADD_TABLE(component),
1090     ADD_TABLE(directory),
1091     ADD_TABLE(feature),
1092     ADD_TABLE(feature_comp),
1093     ADD_TABLE(file),
1094     ADD_TABLE(pp_install_exec_seq),
1095     ADD_TABLE(media),
1096     ADD_TABLE(up2_property),
1097     ADD_TABLE(registry),
1098     ADD_TABLE(service_install),
1099     ADD_TABLE(service_control)
1100 };
1101
1102 static const msi_table up7_tables[] =
1103 {
1104     ADD_TABLE(component),
1105     ADD_TABLE(directory),
1106     ADD_TABLE(feature),
1107     ADD_TABLE(feature_comp),
1108     ADD_TABLE(file),
1109     ADD_TABLE(pp_install_exec_seq),
1110     ADD_TABLE(media),
1111     ADD_TABLE(up3_property),
1112     ADD_TABLE(registry),
1113     ADD_TABLE(service_install),
1114     ADD_TABLE(service_control)
1115 };
1116
1117 static const msi_table cc_tables[] =
1118 {
1119     ADD_TABLE(cc_component),
1120     ADD_TABLE(directory),
1121     ADD_TABLE(cc_feature),
1122     ADD_TABLE(cc_feature_comp),
1123     ADD_TABLE(cc_file),
1124     ADD_TABLE(install_exec_seq),
1125     ADD_TABLE(cc_media),
1126     ADD_TABLE(property),
1127 };
1128
1129 static const msi_table cc2_tables[] =
1130 {
1131     ADD_TABLE(cc2_component),
1132     ADD_TABLE(directory),
1133     ADD_TABLE(cc_feature),
1134     ADD_TABLE(cc_feature_comp),
1135     ADD_TABLE(cc2_file),
1136     ADD_TABLE(install_exec_seq),
1137     ADD_TABLE(cc_media),
1138     ADD_TABLE(property),
1139 };
1140
1141 static const msi_table co_tables[] =
1142 {
1143     ADD_TABLE(cc_component),
1144     ADD_TABLE(directory),
1145     ADD_TABLE(cc_feature),
1146     ADD_TABLE(cc_feature_comp),
1147     ADD_TABLE(co_file),
1148     ADD_TABLE(install_exec_seq),
1149     ADD_TABLE(co_media),
1150     ADD_TABLE(property),
1151 };
1152
1153 static const msi_table co2_tables[] =
1154 {
1155     ADD_TABLE(cc_component),
1156     ADD_TABLE(directory),
1157     ADD_TABLE(cc_feature),
1158     ADD_TABLE(cc_feature_comp),
1159     ADD_TABLE(cc_file),
1160     ADD_TABLE(install_exec_seq),
1161     ADD_TABLE(co2_media),
1162     ADD_TABLE(property),
1163 };
1164
1165 static const msi_table mm_tables[] =
1166 {
1167     ADD_TABLE(cc_component),
1168     ADD_TABLE(directory),
1169     ADD_TABLE(cc_feature),
1170     ADD_TABLE(cc_feature_comp),
1171     ADD_TABLE(mm_file),
1172     ADD_TABLE(install_exec_seq),
1173     ADD_TABLE(mm_media),
1174     ADD_TABLE(property),
1175 };
1176
1177 static const msi_table ss_tables[] =
1178 {
1179     ADD_TABLE(cc_component),
1180     ADD_TABLE(directory),
1181     ADD_TABLE(cc_feature),
1182     ADD_TABLE(cc_feature_comp),
1183     ADD_TABLE(cc_file),
1184     ADD_TABLE(install_exec_seq),
1185     ADD_TABLE(ss_media),
1186     ADD_TABLE(property),
1187 };
1188
1189 static const msi_table ui_tables[] =
1190 {
1191     ADD_TABLE(ui_component),
1192     ADD_TABLE(directory),
1193     ADD_TABLE(cc_feature),
1194     ADD_TABLE(cc_feature_comp),
1195     ADD_TABLE(cc_file),
1196     ADD_TABLE(install_exec_seq),
1197     ADD_TABLE(ui_install_ui_seq),
1198     ADD_TABLE(ui_custom_action),
1199     ADD_TABLE(cc_media),
1200     ADD_TABLE(property),
1201 };
1202
1203 static const msi_table rof_tables[] =
1204 {
1205     ADD_TABLE(rof_component),
1206     ADD_TABLE(directory),
1207     ADD_TABLE(rof_feature),
1208     ADD_TABLE(rof_feature_comp),
1209     ADD_TABLE(rof_file),
1210     ADD_TABLE(install_exec_seq),
1211     ADD_TABLE(rof_media),
1212     ADD_TABLE(property),
1213 };
1214
1215 static const msi_table rofc_tables[] =
1216 {
1217     ADD_TABLE(rof_component),
1218     ADD_TABLE(directory),
1219     ADD_TABLE(rof_feature),
1220     ADD_TABLE(rof_feature_comp),
1221     ADD_TABLE(rofc_file),
1222     ADD_TABLE(install_exec_seq),
1223     ADD_TABLE(rofc_media),
1224     ADD_TABLE(property),
1225 };
1226
1227 static const msi_table sdp_tables[] =
1228 {
1229     ADD_TABLE(rof_component),
1230     ADD_TABLE(directory),
1231     ADD_TABLE(rof_feature),
1232     ADD_TABLE(rof_feature_comp),
1233     ADD_TABLE(rof_file),
1234     ADD_TABLE(sdp_install_exec_seq),
1235     ADD_TABLE(sdp_custom_action),
1236     ADD_TABLE(rof_media),
1237     ADD_TABLE(property),
1238 };
1239
1240 static const msi_table cie_tables[] =
1241 {
1242     ADD_TABLE(cie_component),
1243     ADD_TABLE(directory),
1244     ADD_TABLE(cc_feature),
1245     ADD_TABLE(cie_feature_comp),
1246     ADD_TABLE(cie_file),
1247     ADD_TABLE(install_exec_seq),
1248     ADD_TABLE(cie_media),
1249     ADD_TABLE(property),
1250 };
1251
1252 static const msi_table ci_tables[] =
1253 {
1254     ADD_TABLE(ci_component),
1255     ADD_TABLE(directory),
1256     ADD_TABLE(rof_feature),
1257     ADD_TABLE(rof_feature_comp),
1258     ADD_TABLE(rof_file),
1259     ADD_TABLE(ci_install_exec_seq),
1260     ADD_TABLE(rof_media),
1261     ADD_TABLE(property),
1262     ADD_TABLE(ci_custom_action),
1263 };
1264
1265 static const msi_table ci2_tables[] =
1266 {
1267     ADD_TABLE(ci2_component),
1268     ADD_TABLE(directory),
1269     ADD_TABLE(rof_feature),
1270     ADD_TABLE(ci2_feature_comp),
1271     ADD_TABLE(ci2_file),
1272     ADD_TABLE(install_exec_seq),
1273     ADD_TABLE(rof_media),
1274     ADD_TABLE(property),
1275 };
1276
1277 static const msi_table spf_tables[] =
1278 {
1279     ADD_TABLE(ci_component),
1280     ADD_TABLE(directory),
1281     ADD_TABLE(rof_feature),
1282     ADD_TABLE(rof_feature_comp),
1283     ADD_TABLE(rof_file),
1284     ADD_TABLE(spf_install_exec_seq),
1285     ADD_TABLE(rof_media),
1286     ADD_TABLE(property),
1287     ADD_TABLE(spf_custom_action),
1288     ADD_TABLE(spf_install_ui_seq),
1289 };
1290
1291 static const msi_table pp_tables[] =
1292 {
1293     ADD_TABLE(ci_component),
1294     ADD_TABLE(directory),
1295     ADD_TABLE(rof_feature),
1296     ADD_TABLE(rof_feature_comp),
1297     ADD_TABLE(rof_file),
1298     ADD_TABLE(pp_install_exec_seq),
1299     ADD_TABLE(rof_media),
1300     ADD_TABLE(property),
1301 };
1302
1303 static const msi_table ppc_tables[] =
1304 {
1305     ADD_TABLE(ppc_component),
1306     ADD_TABLE(directory),
1307     ADD_TABLE(rof_feature),
1308     ADD_TABLE(ppc_feature_comp),
1309     ADD_TABLE(ppc_file),
1310     ADD_TABLE(pp_install_exec_seq),
1311     ADD_TABLE(ppc_media),
1312     ADD_TABLE(property),
1313 };
1314
1315 static const msi_table lus0_tables[] =
1316 {
1317     ADD_TABLE(ci_component),
1318     ADD_TABLE(directory),
1319     ADD_TABLE(rof_feature),
1320     ADD_TABLE(rof_feature_comp),
1321     ADD_TABLE(rof_file),
1322     ADD_TABLE(pp_install_exec_seq),
1323     ADD_TABLE(rof_media),
1324     ADD_TABLE(property),
1325 };
1326
1327 static const msi_table lus1_tables[] =
1328 {
1329     ADD_TABLE(ci_component),
1330     ADD_TABLE(directory),
1331     ADD_TABLE(rof_feature),
1332     ADD_TABLE(rof_feature_comp),
1333     ADD_TABLE(rof_file),
1334     ADD_TABLE(pp_install_exec_seq),
1335     ADD_TABLE(rofc_media),
1336     ADD_TABLE(property),
1337 };
1338
1339 static const msi_table lus2_tables[] =
1340 {
1341     ADD_TABLE(ci_component),
1342     ADD_TABLE(directory),
1343     ADD_TABLE(rof_feature),
1344     ADD_TABLE(rof_feature_comp),
1345     ADD_TABLE(rof_file),
1346     ADD_TABLE(pp_install_exec_seq),
1347     ADD_TABLE(lus2_media),
1348     ADD_TABLE(property),
1349 };
1350
1351 static const msi_table tp_tables[] =
1352 {
1353     ADD_TABLE(tp_component),
1354     ADD_TABLE(directory),
1355     ADD_TABLE(rof_feature),
1356     ADD_TABLE(ci2_feature_comp),
1357     ADD_TABLE(ci2_file),
1358     ADD_TABLE(install_exec_seq),
1359     ADD_TABLE(rof_media),
1360     ADD_TABLE(property),
1361 };
1362
1363 static const msi_table cwd_tables[] =
1364 {
1365     ADD_TABLE(cwd_component),
1366     ADD_TABLE(directory),
1367     ADD_TABLE(rof_feature),
1368     ADD_TABLE(ci2_feature_comp),
1369     ADD_TABLE(ci2_file),
1370     ADD_TABLE(install_exec_seq),
1371     ADD_TABLE(rof_media),
1372     ADD_TABLE(property),
1373 };
1374
1375 static const msi_table adm_tables[] =
1376 {
1377     ADD_TABLE(adm_component),
1378     ADD_TABLE(directory),
1379     ADD_TABLE(rof_feature),
1380     ADD_TABLE(ci2_feature_comp),
1381     ADD_TABLE(ci2_file),
1382     ADD_TABLE(install_exec_seq),
1383     ADD_TABLE(rof_media),
1384     ADD_TABLE(property),
1385     ADD_TABLE(adm_custom_action),
1386     ADD_TABLE(adm_admin_exec_seq),
1387 };
1388
1389 static const msi_table amp_tables[] =
1390 {
1391     ADD_TABLE(amp_component),
1392     ADD_TABLE(directory),
1393     ADD_TABLE(rof_feature),
1394     ADD_TABLE(ci2_feature_comp),
1395     ADD_TABLE(ci2_file),
1396     ADD_TABLE(install_exec_seq),
1397     ADD_TABLE(rof_media),
1398     ADD_TABLE(property),
1399 };
1400
1401 static const msi_table rem_tables[] =
1402 {
1403     ADD_TABLE(rem_component),
1404     ADD_TABLE(directory),
1405     ADD_TABLE(rof_feature),
1406     ADD_TABLE(rem_feature_comp),
1407     ADD_TABLE(rem_file),
1408     ADD_TABLE(rem_install_exec_seq),
1409     ADD_TABLE(rof_media),
1410     ADD_TABLE(property),
1411     ADD_TABLE(rem_remove_files),
1412 };
1413
1414 static const msi_table mov_tables[] =
1415 {
1416     ADD_TABLE(cwd_component),
1417     ADD_TABLE(directory),
1418     ADD_TABLE(rof_feature),
1419     ADD_TABLE(ci2_feature_comp),
1420     ADD_TABLE(ci2_file),
1421     ADD_TABLE(install_exec_seq),
1422     ADD_TABLE(rof_media),
1423     ADD_TABLE(property),
1424     ADD_TABLE(mov_move_file),
1425 };
1426
1427 static const msi_table mc_tables[] =
1428 {
1429     ADD_TABLE(mc_component),
1430     ADD_TABLE(directory),
1431     ADD_TABLE(cc_feature),
1432     ADD_TABLE(cie_feature_comp),
1433     ADD_TABLE(mc_file),
1434     ADD_TABLE(install_exec_seq),
1435     ADD_TABLE(mc_media),
1436     ADD_TABLE(property),
1437     ADD_TABLE(mc_file_hash),
1438 };
1439
1440 static const msi_table df_tables[] =
1441 {
1442     ADD_TABLE(rof_component),
1443     ADD_TABLE(df_directory),
1444     ADD_TABLE(rof_feature),
1445     ADD_TABLE(rof_feature_comp),
1446     ADD_TABLE(rof_file),
1447     ADD_TABLE(install_exec_seq),
1448     ADD_TABLE(rof_media),
1449     ADD_TABLE(property),
1450     ADD_TABLE(df_duplicate_file),
1451 };
1452
1453 static const msi_table wrv_tables[] =
1454 {
1455     ADD_TABLE(wrv_component),
1456     ADD_TABLE(directory),
1457     ADD_TABLE(rof_feature),
1458     ADD_TABLE(ci2_feature_comp),
1459     ADD_TABLE(ci2_file),
1460     ADD_TABLE(install_exec_seq),
1461     ADD_TABLE(rof_media),
1462     ADD_TABLE(property),
1463     ADD_TABLE(wrv_registry),
1464 };
1465
1466 static const msi_table sf_tables[] =
1467 {
1468     ADD_TABLE(wrv_component),
1469     ADD_TABLE(directory),
1470     ADD_TABLE(rof_feature),
1471     ADD_TABLE(ci2_feature_comp),
1472     ADD_TABLE(ci2_file),
1473     ADD_TABLE(install_exec_seq),
1474     ADD_TABLE(rof_media),
1475     ADD_TABLE(property),
1476 };
1477
1478 static const msi_table ca51_tables[] =
1479 {
1480     ADD_TABLE(ca51_component),
1481     ADD_TABLE(directory),
1482     ADD_TABLE(rof_feature),
1483     ADD_TABLE(ci2_feature_comp),
1484     ADD_TABLE(ci2_file),
1485     ADD_TABLE(ca51_install_exec_seq),
1486     ADD_TABLE(rof_media),
1487     ADD_TABLE(property),
1488     ADD_TABLE(ca51_custom_action),
1489 };
1490
1491 static const msi_table is_tables[] =
1492 {
1493     ADD_TABLE(is_component),
1494     ADD_TABLE(directory),
1495     ADD_TABLE(is_feature),
1496     ADD_TABLE(is_feature_comp),
1497     ADD_TABLE(is_file),
1498     ADD_TABLE(install_exec_seq),
1499     ADD_TABLE(is_media),
1500     ADD_TABLE(property),
1501 };
1502
1503 static const msi_table sp_tables[] =
1504 {
1505     ADD_TABLE(sp_component),
1506     ADD_TABLE(sp_directory),
1507     ADD_TABLE(rof_feature),
1508     ADD_TABLE(ci2_feature_comp),
1509     ADD_TABLE(ci2_file),
1510     ADD_TABLE(install_exec_seq),
1511     ADD_TABLE(rof_media),
1512     ADD_TABLE(property),
1513 };
1514
1515 static const msi_table mcp_tables[] =
1516 {
1517     ADD_TABLE(mcp_component),
1518     ADD_TABLE(directory),
1519     ADD_TABLE(mcp_feature),
1520     ADD_TABLE(mcp_feature_comp),
1521     ADD_TABLE(rem_file),
1522     ADD_TABLE(rem_install_exec_seq),
1523     ADD_TABLE(rof_media),
1524     ADD_TABLE(property),
1525 };
1526
1527 static const msi_table mcomp_tables[] =
1528 {
1529     ADD_TABLE(mcp_component),
1530     ADD_TABLE(directory),
1531     ADD_TABLE(mcp_feature),
1532     ADD_TABLE(mcp_feature_comp),
1533     ADD_TABLE(mcomp_file),
1534     ADD_TABLE(rem_install_exec_seq),
1535     ADD_TABLE(rof_media),
1536     ADD_TABLE(property),
1537 };
1538
1539 static const msi_table ai_tables[] =
1540 {
1541     ADD_TABLE(component),
1542     ADD_TABLE(directory),
1543     ADD_TABLE(feature),
1544     ADD_TABLE(feature_comp),
1545     ADD_TABLE(ai_file),
1546     ADD_TABLE(install_exec_seq),
1547     ADD_TABLE(media),
1548     ADD_TABLE(property)
1549 };
1550
1551 static const msi_table pc_tables[] =
1552 {
1553     ADD_TABLE(ca51_component),
1554     ADD_TABLE(directory),
1555     ADD_TABLE(rof_feature),
1556     ADD_TABLE(ci2_feature_comp),
1557     ADD_TABLE(ci2_file),
1558     ADD_TABLE(install_exec_seq),
1559     ADD_TABLE(rof_media),
1560     ADD_TABLE(property)
1561 };
1562
1563 static const msi_table ip_tables[] =
1564 {
1565     ADD_TABLE(component),
1566     ADD_TABLE(directory),
1567     ADD_TABLE(feature),
1568     ADD_TABLE(feature_comp),
1569     ADD_TABLE(file),
1570     ADD_TABLE(ip_install_exec_seq),
1571     ADD_TABLE(ip_custom_action),
1572     ADD_TABLE(media),
1573     ADD_TABLE(property)
1574 };
1575
1576 static const msi_table aup_tables[] =
1577 {
1578     ADD_TABLE(component),
1579     ADD_TABLE(directory),
1580     ADD_TABLE(feature),
1581     ADD_TABLE(feature_comp),
1582     ADD_TABLE(file),
1583     ADD_TABLE(aup_install_exec_seq),
1584     ADD_TABLE(aup_custom_action),
1585     ADD_TABLE(media),
1586     ADD_TABLE(property)
1587 };
1588
1589 static const msi_table fiu_tables[] =
1590 {
1591     ADD_TABLE(rof_component),
1592     ADD_TABLE(directory),
1593     ADD_TABLE(rof_feature),
1594     ADD_TABLE(rof_feature_comp),
1595     ADD_TABLE(rof_file),
1596     ADD_TABLE(pp_install_exec_seq),
1597     ADD_TABLE(rof_media),
1598     ADD_TABLE(property),
1599 };
1600
1601 static const msi_table fiuc_tables[] =
1602 {
1603     ADD_TABLE(rof_component),
1604     ADD_TABLE(directory),
1605     ADD_TABLE(rof_feature),
1606     ADD_TABLE(rof_feature_comp),
1607     ADD_TABLE(rofc_file),
1608     ADD_TABLE(pp_install_exec_seq),
1609     ADD_TABLE(rofc_media),
1610     ADD_TABLE(property),
1611 };
1612
1613 /* cabinet definitions */
1614
1615 /* make the max size large so there is only one cab file */
1616 #define MEDIA_SIZE          0x7FFFFFFF
1617 #define FOLDER_THRESHOLD    900000
1618
1619 /* the FCI callbacks */
1620
1621 static void * CDECL mem_alloc(ULONG cb)
1622 {
1623     return HeapAlloc(GetProcessHeap(), 0, cb);
1624 }
1625
1626 static void CDECL mem_free(void *memory)
1627 {
1628     HeapFree(GetProcessHeap(), 0, memory);
1629 }
1630
1631 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
1632 {
1633     sprintf(pccab->szCab, pv, pccab->iCab);
1634     return TRUE;
1635 }
1636
1637 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
1638 {
1639     return 0;
1640 }
1641
1642 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
1643                              BOOL fContinuation, void *pv)
1644 {
1645     return 0;
1646 }
1647
1648 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
1649 {
1650     HANDLE handle;
1651     DWORD dwAccess = 0;
1652     DWORD dwShareMode = 0;
1653     DWORD dwCreateDisposition = OPEN_EXISTING;
1654     
1655     dwAccess = GENERIC_READ | GENERIC_WRITE;
1656     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
1657     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1658
1659     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
1660         dwCreateDisposition = OPEN_EXISTING;
1661     else
1662         dwCreateDisposition = CREATE_NEW;
1663
1664     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
1665                          dwCreateDisposition, 0, NULL);
1666
1667     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
1668
1669     return (INT_PTR)handle;
1670 }
1671
1672 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1673 {
1674     HANDLE handle = (HANDLE)hf;
1675     DWORD dwRead;
1676     BOOL res;
1677     
1678     res = ReadFile(handle, memory, cb, &dwRead, NULL);
1679     ok(res, "Failed to ReadFile\n");
1680
1681     return dwRead;
1682 }
1683
1684 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1685 {
1686     HANDLE handle = (HANDLE)hf;
1687     DWORD dwWritten;
1688     BOOL res;
1689
1690     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
1691     ok(res, "Failed to WriteFile\n");
1692
1693     return dwWritten;
1694 }
1695
1696 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
1697 {
1698     HANDLE handle = (HANDLE)hf;
1699     ok(CloseHandle(handle), "Failed to CloseHandle\n");
1700
1701     return 0;
1702 }
1703
1704 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
1705 {
1706     HANDLE handle = (HANDLE)hf;
1707     DWORD ret;
1708     
1709     ret = SetFilePointer(handle, dist, NULL, seektype);
1710     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
1711
1712     return ret;
1713 }
1714
1715 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
1716 {
1717     BOOL ret = DeleteFileA(pszFile);
1718     ok(ret, "Failed to DeleteFile %s\n", pszFile);
1719
1720     return 0;
1721 }
1722
1723 static void init_functionpointers(void)
1724 {
1725     HMODULE hmsi = GetModuleHandleA("msi.dll");
1726     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
1727
1728 #define GET_PROC(mod, func) \
1729     p ## func = (void*)GetProcAddress(mod, #func); \
1730     if(!p ## func) \
1731       trace("GetProcAddress(%s) failed\n", #func);
1732
1733     GET_PROC(hmsi, MsiQueryComponentStateA);
1734     GET_PROC(hmsi, MsiSetExternalUIRecord);
1735     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
1736     GET_PROC(hmsi, MsiSourceListGetInfoA);
1737
1738     GET_PROC(hadvapi32, ConvertSidToStringSidA);
1739
1740     hsrclient = LoadLibraryA("srclient.dll");
1741     GET_PROC(hsrclient, SRRemoveRestorePoint);
1742     GET_PROC(hsrclient, SRSetRestorePointA);
1743
1744 #undef GET_PROC
1745 }
1746
1747 static BOOL check_win9x(void)
1748 {
1749     SC_HANDLE scm;
1750
1751     scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
1752     if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1753         return TRUE;
1754
1755     CloseServiceHandle(scm);
1756
1757     return FALSE;
1758 }
1759
1760 static LPSTR get_user_sid(LPSTR *usersid)
1761 {
1762     HANDLE token;
1763     BYTE buf[1024];
1764     DWORD size;
1765     PTOKEN_USER user;
1766
1767     if (!pConvertSidToStringSidA)
1768     {
1769         win_skip("ConvertSidToStringSidA is not available\n");
1770         return NULL;
1771     }
1772
1773     *usersid = NULL;
1774     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1775     size = sizeof(buf);
1776     GetTokenInformation(token, TokenUser, buf, size, &size);
1777     user = (PTOKEN_USER)buf;
1778     pConvertSidToStringSidA(user->User.Sid, usersid);
1779     ok(*usersid != NULL, "pConvertSidToStringSidA failed lre=%d\n", GetLastError());
1780     CloseHandle(token);
1781     return *usersid;
1782 }
1783
1784 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
1785 {
1786     CHAR buffer[0x20];
1787     UINT r;
1788     DWORD sz;
1789
1790     sz = sizeof buffer;
1791     r = MsiRecordGetString(rec, field, buffer, &sz);
1792     return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1793 }
1794
1795 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
1796 {
1797     LPSTR tempname;
1798
1799     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
1800     GetTempFileNameA(".", "xx", 0, tempname);
1801
1802     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
1803     {
1804         lstrcpyA(pszTempName, tempname);
1805         HeapFree(GetProcessHeap(), 0, tempname);
1806         return TRUE;
1807     }
1808
1809     HeapFree(GetProcessHeap(), 0, tempname);
1810
1811     return FALSE;
1812 }
1813
1814 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
1815                                    USHORT *pattribs, int *err, void *pv)
1816 {
1817     BY_HANDLE_FILE_INFORMATION finfo;
1818     FILETIME filetime;
1819     HANDLE handle;
1820     DWORD attrs;
1821     BOOL res;
1822
1823     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
1824                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1825
1826     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
1827
1828     res = GetFileInformationByHandle(handle, &finfo);
1829     ok(res, "Expected GetFileInformationByHandle to succeed\n");
1830    
1831     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
1832     FileTimeToDosDateTime(&filetime, pdate, ptime);
1833
1834     attrs = GetFileAttributes(pszName);
1835     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
1836
1837     return (INT_PTR)handle;
1838 }
1839
1840 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
1841 {
1842     char path[MAX_PATH];
1843     char filename[MAX_PATH];
1844
1845     lstrcpyA(path, CURR_DIR);
1846     lstrcatA(path, "\\");
1847     lstrcatA(path, file);
1848
1849     lstrcpyA(filename, file);
1850
1851     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
1852                       progress, get_open_info, compress);
1853 }
1854
1855 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
1856 {
1857     ZeroMemory(pCabParams, sizeof(CCAB));
1858
1859     pCabParams->cb = max_size;
1860     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
1861     pCabParams->setID = 0xbeef;
1862     pCabParams->iCab = 1;
1863     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
1864     lstrcatA(pCabParams->szCabPath, "\\");
1865     lstrcpyA(pCabParams->szCab, name);
1866 }
1867
1868 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
1869 {
1870     CCAB cabParams;
1871     LPCSTR ptr;
1872     HFCI hfci;
1873     ERF erf;
1874     BOOL res;
1875
1876     set_cab_parameters(&cabParams, name, max_size);
1877
1878     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1879                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
1880                       get_temp_file, &cabParams, NULL);
1881
1882     ok(hfci != NULL, "Failed to create an FCI context\n");
1883
1884     ptr = files;
1885     while (*ptr)
1886     {
1887         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
1888         ok(res, "Failed to add file: %s\n", ptr);
1889         ptr += lstrlen(ptr) + 1;
1890     }
1891
1892     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1893     ok(res, "Failed to flush the cabinet\n");
1894
1895     res = FCIDestroy(hfci);
1896     ok(res, "Failed to destroy the cabinet\n");
1897 }
1898
1899 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1900 {
1901     HKEY hkey;
1902     DWORD type, size;
1903
1904     if (RegOpenKey(HKEY_LOCAL_MACHINE,
1905                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1906         return FALSE;
1907
1908     size = MAX_PATH;
1909     if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1910         RegCloseKey(hkey);
1911         return FALSE;
1912     }
1913
1914     size = MAX_PATH;
1915     if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1916         RegCloseKey(hkey);
1917         return FALSE;
1918     }
1919
1920     RegCloseKey(hkey);
1921     return TRUE;
1922 }
1923
1924 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1925 {
1926     HANDLE file;
1927     DWORD written;
1928
1929     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1930     if (file == INVALID_HANDLE_VALUE)
1931         return;
1932
1933     WriteFile(file, data, strlen(data), &written, NULL);
1934
1935     if (size)
1936     {
1937         SetFilePointer(file, size, NULL, FILE_BEGIN);
1938         SetEndOfFile(file);
1939     }
1940
1941     CloseHandle(file);
1942 }
1943
1944 #define create_file(name, size) create_file_data(name, name, size)
1945
1946 static void create_test_files(void)
1947 {
1948     CreateDirectoryA("msitest", NULL);
1949     create_file("msitest\\one.txt", 100);
1950     CreateDirectoryA("msitest\\first", NULL);
1951     create_file("msitest\\first\\two.txt", 100);
1952     CreateDirectoryA("msitest\\second", NULL);
1953     create_file("msitest\\second\\three.txt", 100);
1954
1955     create_file("four.txt", 100);
1956     create_file("five.txt", 100);
1957     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1958
1959     create_file("msitest\\filename", 100);
1960     create_file("msitest\\service.exe", 100);
1961
1962     DeleteFileA("four.txt");
1963     DeleteFileA("five.txt");
1964 }
1965
1966 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1967 {
1968     CHAR path[MAX_PATH];
1969
1970     lstrcpyA(path, PROG_FILES_DIR);
1971     lstrcatA(path, "\\");
1972     lstrcatA(path, rel_path);
1973
1974     if (is_file)
1975         return DeleteFileA(path);
1976     else
1977         return RemoveDirectoryA(path);
1978 }
1979
1980 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1981 {
1982     CHAR path[MAX_PATH];
1983
1984     lstrcpyA(path, COMMON_FILES_DIR);
1985     lstrcatA(path, "\\");
1986     lstrcatA(path, rel_path);
1987
1988     if (is_file)
1989         return DeleteFileA(path);
1990     else
1991         return RemoveDirectoryA(path);
1992 }
1993
1994 static void delete_test_files(void)
1995 {
1996     DeleteFileA("msitest.msi");
1997     DeleteFileA("msitest.cab");
1998     DeleteFileA("msitest\\second\\three.txt");
1999     DeleteFileA("msitest\\first\\two.txt");
2000     DeleteFileA("msitest\\one.txt");
2001     DeleteFileA("msitest\\service.exe");
2002     DeleteFileA("msitest\\filename");
2003     RemoveDirectoryA("msitest\\second");
2004     RemoveDirectoryA("msitest\\first");
2005     RemoveDirectoryA("msitest");
2006 }
2007
2008 static void write_file(const CHAR *filename, const char *data, int data_size)
2009 {
2010     DWORD size;
2011
2012     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
2013                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2014
2015     WriteFile(hf, data, data_size, &size, NULL);
2016     CloseHandle(hf);
2017 }
2018
2019 static void write_msi_summary_info(MSIHANDLE db, INT wordcount)
2020 {
2021     MSIHANDLE summary;
2022     UINT r;
2023
2024     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
2025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2026
2027     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
2028     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2029
2030     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2031                                    "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
2032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2033
2034     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
2035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2036
2037     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
2038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2039
2040     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2042
2043     /* write the summary changes back to the stream */
2044     r = MsiSummaryInfoPersist(summary);
2045     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2046
2047     MsiCloseHandle(summary);
2048 }
2049
2050 #define create_database(name, tables, num_tables) \
2051     create_database_wordcount(name, tables, num_tables, 0);
2052
2053 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
2054                                       int num_tables, INT wordcount)
2055 {
2056     MSIHANDLE db;
2057     UINT r;
2058     int j;
2059
2060     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
2061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2062
2063     /* import the tables into the database */
2064     for (j = 0; j < num_tables; j++)
2065     {
2066         const msi_table *table = &tables[j];
2067
2068         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
2069
2070         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
2071         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2072
2073         DeleteFileA(table->filename);
2074     }
2075
2076     write_msi_summary_info(db, wordcount);
2077
2078     r = MsiDatabaseCommit(db);
2079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2080
2081     MsiCloseHandle(db);
2082 }
2083
2084 static void check_service_is_installed(void)
2085 {
2086     SC_HANDLE scm, service;
2087     BOOL res;
2088
2089     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
2090     ok(scm != NULL, "Failed to open the SC Manager\n");
2091
2092     service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
2093     ok(service != NULL, "Failed to open TestService\n");
2094
2095     res = DeleteService(service);
2096     ok(res, "Failed to delete TestService\n");
2097
2098     CloseServiceHandle(service);
2099     CloseServiceHandle(scm);
2100 }
2101
2102 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
2103 {
2104     RESTOREPOINTINFOA spec;
2105
2106     spec.dwEventType = event_type;
2107     spec.dwRestorePtType = APPLICATION_INSTALL;
2108     spec.llSequenceNumber = status->llSequenceNumber;
2109     lstrcpyA(spec.szDescription, "msitest restore point");
2110
2111     return pSRSetRestorePointA(&spec, status);
2112 }
2113
2114 static void remove_restore_point(DWORD seq_number)
2115 {
2116     DWORD res;
2117
2118     res = pSRRemoveRestorePoint(seq_number);
2119     if (res != ERROR_SUCCESS)
2120         trace("Failed to remove the restore point : %08x\n", res);
2121 }
2122
2123 static void test_MsiInstallProduct(void)
2124 {
2125     UINT r;
2126     CHAR path[MAX_PATH];
2127     LONG res;
2128     HKEY hkey;
2129     DWORD num, size, type;
2130
2131     if (on_win9x)
2132     {
2133         win_skip("Services are not implemented on Win9x and WinMe\n");
2134         return;
2135     }
2136
2137     /* szPackagePath is NULL */
2138     r = MsiInstallProductA(NULL, "INSTALL=ALL");
2139     ok(r == ERROR_INVALID_PARAMETER,
2140        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2141
2142     /* both szPackagePath and szCommandLine are NULL */
2143     r = MsiInstallProductA(NULL, NULL);
2144     ok(r == ERROR_INVALID_PARAMETER,
2145        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2146
2147     /* szPackagePath is empty */
2148     r = MsiInstallProductA("", "INSTALL=ALL");
2149     ok(r == ERROR_PATH_NOT_FOUND,
2150        "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
2151
2152     create_test_files();
2153     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
2154
2155     /* install, don't publish */
2156     r = MsiInstallProductA(msifile, NULL);
2157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2158
2159     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2160     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2161     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2162     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2163     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2164     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2165     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2166     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2167     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2168     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2169     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2170     ok(delete_pf("msitest", FALSE), "File not installed\n");
2171
2172     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2174
2175     size = MAX_PATH;
2176     type = REG_SZ;
2177     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
2178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2179     ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
2180
2181     size = MAX_PATH;
2182     type = REG_SZ;
2183     res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
2184     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2185
2186     size = sizeof(num);
2187     type = REG_DWORD;
2188     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
2189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2190     ok(num == 314, "Expected 314, got %d\n", num);
2191
2192     size = MAX_PATH;
2193     type = REG_SZ;
2194     res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
2195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2196     ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
2197
2198     check_service_is_installed();
2199
2200     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
2201
2202     /* not published, reinstall */
2203     r = MsiInstallProductA(msifile, NULL);
2204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2205
2206     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2207     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2208     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2209     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2210     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2211     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2212     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2213     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2214     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2215     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2216     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2217     ok(delete_pf("msitest", FALSE), "File not installed\n");
2218
2219     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2221     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
2222
2223     create_database(msifile, up_tables, sizeof(up_tables) / sizeof(msi_table));
2224
2225     /* not published, RemovePreviousVersions set */
2226     r = MsiInstallProductA(msifile, NULL);
2227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2228
2229     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2230     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2231     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2232     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2233     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2234     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2235     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2236     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2237     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2238     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2239     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2240     ok(delete_pf("msitest", FALSE), "File not installed\n");
2241
2242     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2244     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
2245
2246     create_database(msifile, up2_tables, sizeof(up2_tables) / sizeof(msi_table));
2247
2248     /* not published, version number bumped */
2249     r = MsiInstallProductA(msifile, NULL);
2250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2251
2252     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2253     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2254     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2255     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2256     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2257     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2258     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2259     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2260     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2261     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2262     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2263     ok(delete_pf("msitest", FALSE), "File not installed\n");
2264
2265     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2267     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
2268
2269     create_database(msifile, up3_tables, sizeof(up3_tables) / sizeof(msi_table));
2270
2271     /* not published, RemovePreviousVersions set and version number bumped */
2272     r = MsiInstallProductA(msifile, NULL);
2273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2274
2275     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2276     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2277     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2278     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2279     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2280     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2281     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2282     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2283     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2284     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2285     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2286     ok(delete_pf("msitest", FALSE), "File not installed\n");
2287
2288     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2290     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
2291
2292     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
2293
2294     /* install, publish product */
2295     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2297
2298     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2299     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2300     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2301     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2302     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2303     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2304     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2305     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2306     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2307     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2308     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2309     ok(delete_pf("msitest", FALSE), "File not installed\n");
2310
2311     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2312     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2313
2314     create_database(msifile, up4_tables, sizeof(up4_tables) / sizeof(msi_table));
2315
2316     /* published, reinstall */
2317     r = MsiInstallProductA(msifile, NULL);
2318     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2319
2320     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2321     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2322     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2323     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2324     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2325     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2326     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2327     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2328     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2329     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2330     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2331     ok(delete_pf("msitest", FALSE), "File not installed\n");
2332
2333     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2334     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2335
2336     create_database(msifile, up5_tables, sizeof(up5_tables) / sizeof(msi_table));
2337
2338     /* published product, RemovePreviousVersions set */
2339     r = MsiInstallProductA(msifile, NULL);
2340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2341
2342     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2343     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2344     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2345     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2346     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2347     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2348     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2349     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2350     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2351     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2352     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2353     ok(delete_pf("msitest", FALSE), "File not installed\n");
2354
2355     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2356     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2357
2358     create_database(msifile, up6_tables, sizeof(up6_tables) / sizeof(msi_table));
2359
2360     /* published product, version number bumped */
2361     r = MsiInstallProductA(msifile, NULL);
2362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2363
2364     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2365     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2366     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2367     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2368     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2369     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2370     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2371     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2372     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2373     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2374     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2375     ok(delete_pf("msitest", FALSE), "File not installed\n");
2376
2377     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2378     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2379
2380     create_database(msifile, up7_tables, sizeof(up7_tables) / sizeof(msi_table));
2381
2382     /* published product, RemovePreviousVersions set and version number bumped */
2383     r = MsiInstallProductA(msifile, NULL);
2384     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2385
2386     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2387     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
2388     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2389     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
2390     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2391     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
2392     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2393     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
2394     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2395     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2396     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
2397     ok(delete_pf("msitest", FALSE), "File not installed\n");
2398
2399     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
2400     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2401
2402     r = MsiInstallProductA(msifile, "REMOVE=ALL");
2403     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2404
2405     delete_test_files();
2406 }
2407
2408 static void test_MsiSetComponentState(void)
2409 {
2410     INSTALLSTATE installed, action;
2411     MSIHANDLE package;
2412     char path[MAX_PATH];
2413     UINT r;
2414
2415     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
2416
2417     CoInitialize(NULL);
2418
2419     lstrcpy(path, CURR_DIR);
2420     lstrcat(path, "\\");
2421     lstrcat(path, msifile);
2422
2423     r = MsiOpenPackage(path, &package);
2424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2425
2426     r = MsiDoAction(package, "CostInitialize");
2427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2428
2429     r = MsiDoAction(package, "FileCost");
2430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2431
2432     r = MsiDoAction(package, "CostFinalize");
2433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2434
2435     r = MsiGetComponentState(package, "dangler", &installed, &action);
2436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2437     ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
2438     ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2439
2440     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
2441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2442
2443     MsiCloseHandle(package);
2444     CoUninitialize();
2445
2446     DeleteFileA(msifile);
2447 }
2448
2449 static void test_packagecoltypes(void)
2450 {
2451     MSIHANDLE hdb, view, rec;
2452     char path[MAX_PATH];
2453     LPCSTR query;
2454     UINT r, count;
2455
2456     create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
2457
2458     CoInitialize(NULL);
2459
2460     lstrcpy(path, CURR_DIR);
2461     lstrcat(path, "\\");
2462     lstrcat(path, msifile);
2463
2464     r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
2465     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2466
2467     query = "SELECT * FROM `Media`";
2468     r = MsiDatabaseOpenView( hdb, query, &view );
2469     ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
2470
2471     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
2472     count = MsiRecordGetFieldCount( rec );
2473     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
2474     ok(count == 6, "Expected 6, got %d\n", count);
2475     ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
2476     ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
2477     ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
2478     ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
2479     ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
2480     ok(check_record(rec, 6, "Source"), "wrong column label\n");
2481     MsiCloseHandle(rec);
2482
2483     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
2484     count = MsiRecordGetFieldCount( rec );
2485     ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
2486     ok(count == 6, "Expected 6, got %d\n", count);
2487     ok(check_record(rec, 1, "i2"), "wrong column label\n");
2488     ok(check_record(rec, 2, "i4"), "wrong column label\n");
2489     ok(check_record(rec, 3, "L64"), "wrong column label\n");
2490     ok(check_record(rec, 4, "S255"), "wrong column label\n");
2491     ok(check_record(rec, 5, "S32"), "wrong column label\n");
2492     ok(check_record(rec, 6, "S72"), "wrong column label\n");
2493
2494     MsiCloseHandle(rec);
2495     MsiCloseHandle(view);
2496     MsiCloseHandle(hdb);
2497     CoUninitialize();
2498
2499     DeleteFile(msifile);
2500 }
2501
2502 static void create_cc_test_files(void)
2503 {
2504     CCAB cabParams;
2505     HFCI hfci;
2506     ERF erf;
2507     static CHAR cab_context[] = "test%d.cab";
2508     BOOL res;
2509
2510     create_file("maximus", 500);
2511     create_file("augustus", 50000);
2512     create_file("tiberius", 500);
2513     create_file("caesar", 500);
2514
2515     set_cab_parameters(&cabParams, "test1.cab", 40000);
2516
2517     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2518                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2519                       get_temp_file, &cabParams, cab_context);
2520     ok(hfci != NULL, "Failed to create an FCI context\n");
2521
2522     res = add_file(hfci, "maximus", tcompTYPE_NONE);
2523     ok(res, "Failed to add file maximus\n");
2524
2525     res = add_file(hfci, "augustus", tcompTYPE_NONE);
2526     ok(res, "Failed to add file augustus\n");
2527
2528     res = add_file(hfci, "tiberius", tcompTYPE_NONE);
2529     ok(res, "Failed to add file tiberius\n");
2530
2531     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2532     ok(res, "Failed to flush the cabinet\n");
2533
2534     res = FCIDestroy(hfci);
2535     ok(res, "Failed to destroy the cabinet\n");
2536
2537     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
2538
2539     DeleteFile("maximus");
2540     DeleteFile("augustus");
2541     DeleteFile("tiberius");
2542     DeleteFile("caesar");
2543 }
2544
2545 static void delete_cab_files(void)
2546 {
2547     SHFILEOPSTRUCT shfl;
2548     CHAR path[MAX_PATH+10];
2549
2550     lstrcpyA(path, CURR_DIR);
2551     lstrcatA(path, "\\*.cab");
2552     path[strlen(path) + 1] = '\0';
2553
2554     shfl.hwnd = NULL;
2555     shfl.wFunc = FO_DELETE;
2556     shfl.pFrom = path;
2557     shfl.pTo = NULL;
2558     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
2559
2560     SHFileOperation(&shfl);
2561 }
2562
2563 static void test_continuouscabs(void)
2564 {
2565     UINT r;
2566
2567     create_cc_test_files();
2568     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
2569
2570     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2571
2572     r = MsiInstallProductA(msifile, NULL);
2573     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
2574     {
2575         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2576         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2577         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
2578         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2579         ok(delete_pf("msitest", FALSE), "File not installed\n");
2580     }
2581
2582     delete_cab_files();
2583     DeleteFile(msifile);
2584
2585     create_cc_test_files();
2586     create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
2587
2588     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2589
2590     r = MsiInstallProductA(msifile, NULL);
2591     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2592     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2593     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2594     ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
2595     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
2596     ok(delete_pf("msitest", FALSE), "File not installed\n");
2597
2598     delete_cab_files();
2599     DeleteFile(msifile);
2600 }
2601
2602 static void test_caborder(void)
2603 {
2604     UINT r;
2605
2606     create_file("imperator", 100);
2607     create_file("maximus", 500);
2608     create_file("augustus", 50000);
2609     create_file("caesar", 500);
2610
2611     create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
2612
2613     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2614
2615     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
2616     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
2617     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
2618
2619     r = MsiInstallProductA(msifile, NULL);
2620     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
2621     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
2622     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
2623     todo_wine
2624     {
2625         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
2626         ok(!delete_pf("msitest", FALSE), "File is installed\n");
2627     }
2628
2629     delete_cab_files();
2630
2631     create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
2632     create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
2633     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
2634
2635     r = MsiInstallProductA(msifile, NULL);
2636     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
2637     ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
2638     ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
2639     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
2640     todo_wine
2641     {
2642         ok(!delete_pf("msitest", FALSE), "File is installed\n");
2643     }
2644
2645     delete_cab_files();
2646     DeleteFile(msifile);
2647
2648     create_cc_test_files();
2649     create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
2650
2651     r = MsiInstallProductA(msifile, NULL);
2652     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
2653     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
2654     ok(!delete_pf("msitest", FALSE), "File is installed\n");
2655     todo_wine
2656     {
2657         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
2658         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
2659     }
2660
2661     delete_cab_files();
2662     DeleteFile(msifile);
2663
2664     create_cc_test_files();
2665     create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
2666
2667     r = MsiInstallProductA(msifile, NULL);
2668     ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
2669     todo_wine
2670     {
2671         ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
2672         ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
2673         ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
2674         ok(!delete_pf("msitest", FALSE), "File is installed\n");
2675     }
2676
2677     delete_cab_files();
2678     DeleteFile("imperator");
2679     DeleteFile("maximus");
2680     DeleteFile("augustus");
2681     DeleteFile("caesar");
2682     DeleteFile(msifile);
2683 }
2684
2685 static void test_mixedmedia(void)
2686 {
2687     UINT r;
2688
2689     CreateDirectoryA("msitest", NULL);
2690     create_file("msitest\\maximus", 500);
2691     create_file("msitest\\augustus", 500);
2692     create_file("caesar", 500);
2693
2694     create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
2695
2696     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2697
2698     create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
2699
2700     r = MsiInstallProductA(msifile, NULL);
2701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2702     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2703     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
2704     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2705     ok(delete_pf("msitest", FALSE), "File not installed\n");
2706
2707     /* Delete the files in the temp (current) folder */
2708     DeleteFile("msitest\\maximus");
2709     DeleteFile("msitest\\augustus");
2710     RemoveDirectory("msitest");
2711     DeleteFile("caesar");
2712     DeleteFile("test1.cab");
2713     DeleteFile(msifile);
2714 }
2715
2716 static void test_samesequence(void)
2717 {
2718     UINT r;
2719
2720     create_cc_test_files();
2721     create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
2722
2723     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2724
2725     r = MsiInstallProductA(msifile, NULL);
2726     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
2727     {
2728         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2729         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2730         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
2731         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2732         ok(delete_pf("msitest", FALSE), "File not installed\n");
2733     }
2734
2735     delete_cab_files();
2736     DeleteFile(msifile);
2737 }
2738
2739 static void test_uiLevelFlags(void)
2740 {
2741     UINT r;
2742
2743     create_cc_test_files();
2744     create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
2745
2746     MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
2747
2748     r = MsiInstallProductA(msifile, NULL);
2749     if (r == ERROR_SUCCESS) /* win9x has a problem with this */
2750     {
2751         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2752         ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
2753         ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
2754         ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2755         ok(delete_pf("msitest", FALSE), "File not installed\n");
2756     }
2757
2758     delete_cab_files();
2759     DeleteFile(msifile);
2760 }
2761
2762 static BOOL file_matches(LPSTR path)
2763 {
2764     CHAR buf[MAX_PATH];
2765     HANDLE file;
2766     DWORD size;
2767
2768     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2769                       NULL, OPEN_EXISTING, 0, NULL);
2770
2771     ZeroMemory(buf, MAX_PATH);
2772     ReadFile(file, buf, 15, &size, NULL);
2773     CloseHandle(file);
2774
2775     return !lstrcmp(buf, "msitest\\maximus");
2776 }
2777
2778 static void test_readonlyfile(void)
2779 {
2780     UINT r;
2781     DWORD size;
2782     HANDLE file;
2783     CHAR path[MAX_PATH];
2784
2785     CreateDirectoryA("msitest", NULL);
2786     create_file("msitest\\maximus", 500);
2787     create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
2788
2789     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2790
2791     lstrcpy(path, PROG_FILES_DIR);
2792     lstrcat(path, "\\msitest");
2793     CreateDirectory(path, NULL);
2794
2795     lstrcat(path, "\\maximus");
2796     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2797                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
2798
2799     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
2800     CloseHandle(file);
2801
2802     r = MsiInstallProductA(msifile, NULL);
2803     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2804     ok(file_matches(path), "Expected file to be overwritten\n");
2805     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2806     ok(delete_pf("msitest", FALSE), "File not installed\n");
2807
2808     /* Delete the files in the temp (current) folder */
2809     DeleteFile("msitest\\maximus");
2810     RemoveDirectory("msitest");
2811     DeleteFile(msifile);
2812 }
2813
2814 static void test_readonlyfile_cab(void)
2815 {
2816     UINT r;
2817     DWORD size;
2818     HANDLE file;
2819     CHAR path[MAX_PATH];
2820     CHAR buf[16];
2821
2822     CreateDirectoryA("msitest", NULL);
2823     create_file("maximus", 500);
2824     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
2825     DeleteFile("maximus");
2826
2827     create_database(msifile, rofc_tables, sizeof(rofc_tables) / sizeof(msi_table));
2828
2829     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2830
2831     lstrcpy(path, PROG_FILES_DIR);
2832     lstrcat(path, "\\msitest");
2833     CreateDirectory(path, NULL);
2834
2835     lstrcat(path, "\\maximus");
2836     file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2837                       NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
2838
2839     WriteFile(file, "readonlyfile", strlen("readonlyfile"), &size, NULL);
2840     CloseHandle(file);
2841
2842     r = MsiInstallProductA(msifile, NULL);
2843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2844
2845     memset( buf, 0, sizeof(buf) );
2846     if ((file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2847                            NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
2848     {
2849         ReadFile(file, buf, sizeof(buf) - 1, &size, NULL);
2850         CloseHandle(file);
2851     }
2852     ok( !lstrcmp( buf, "maximus" ), "Expected file to be overwritten, got '%s'\n", buf );
2853     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2854     ok(delete_pf("msitest", FALSE), "File not installed\n");
2855
2856     /* Delete the files in the temp (current) folder */
2857     delete_cab_files();
2858     DeleteFile("msitest\\maximus");
2859     RemoveDirectory("msitest");
2860     DeleteFile(msifile);
2861 }
2862
2863 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
2864 {
2865     WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
2866     IStorage *stg;
2867     IStream *stm;
2868     HRESULT hr;
2869     HANDLE handle;
2870
2871     MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
2872     hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
2873     if (FAILED(hr))
2874         return FALSE;
2875
2876     MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
2877     hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2878     if (FAILED(hr))
2879     {
2880         IStorage_Release(stg);
2881         return FALSE;
2882     }
2883
2884     handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
2885     if (handle != INVALID_HANDLE_VALUE)
2886     {
2887         DWORD count;
2888         char buffer[1024];
2889         if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
2890             IStream_Write(stm, buffer, count, &count);
2891         CloseHandle(handle);
2892     }
2893
2894     IStream_Release(stm);
2895     IStorage_Release(stg);
2896
2897     return TRUE;
2898 }
2899
2900 static void test_lastusedsource(void)
2901 {
2902     static char prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2903
2904     UINT r;
2905     char value[MAX_PATH], path[MAX_PATH];
2906     DWORD size;
2907
2908     if (!pMsiSourceListGetInfoA)
2909     {
2910         win_skip("MsiSourceListGetInfoA is not available\n");
2911         return;
2912     }
2913
2914     CreateDirectoryA("msitest", NULL);
2915     create_file("maximus", 500);
2916     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
2917     DeleteFile("maximus");
2918
2919     create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
2920     create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
2921     create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
2922
2923     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2924
2925     /* no cabinet file */
2926
2927     size = MAX_PATH;
2928     lstrcpyA(value, "aaa");
2929     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2930                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
2931     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
2932     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
2933
2934     r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
2935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2936
2937     lstrcpyA(path, CURR_DIR);
2938     lstrcatA(path, "\\");
2939
2940     size = MAX_PATH;
2941     lstrcpyA(value, "aaa");
2942     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2943                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
2944     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2945     todo_wine
2946     {
2947     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
2948     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
2949     }
2950
2951     r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
2952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2953
2954     /* separate cabinet file */
2955
2956     size = MAX_PATH;
2957     lstrcpyA(value, "aaa");
2958     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2959                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
2960     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
2961     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
2962
2963     r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
2964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2965
2966     lstrcpyA(path, CURR_DIR);
2967     lstrcatA(path, "\\");
2968
2969     size = MAX_PATH;
2970     lstrcpyA(value, "aaa");
2971     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2972                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
2973     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2974     todo_wine
2975     {
2976     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
2977     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
2978     }
2979
2980     r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
2981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2982
2983     size = MAX_PATH;
2984     lstrcpyA(value, "aaa");
2985     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2986                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
2987     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
2988     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
2989
2990     /* embedded cabinet stream */
2991
2992     add_cabinet_storage("msifile2.msi", "test1.cab");
2993
2994     r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
2995     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2996
2997     size = MAX_PATH;
2998     lstrcpyA(value, "aaa");
2999     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3000                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3001     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3002     todo_wine
3003     {
3004     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3005     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3006     }
3007
3008     r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
3009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3010
3011     size = MAX_PATH;
3012     lstrcpyA(value, "aaa");
3013     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3014                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3015     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
3016     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
3017
3018     /* Delete the files in the temp (current) folder */
3019     delete_cab_files();
3020     DeleteFile("msitest\\maximus");
3021     RemoveDirectory("msitest");
3022     DeleteFile("msifile0.msi");
3023     DeleteFile("msifile1.msi");
3024     DeleteFile("msifile2.msi");
3025 }
3026
3027 static void test_setdirproperty(void)
3028 {
3029     UINT r;
3030
3031     CreateDirectoryA("msitest", NULL);
3032     create_file("msitest\\maximus", 500);
3033     create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
3034
3035     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3036
3037     r = MsiInstallProductA(msifile, NULL);
3038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3039     ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
3040     ok(delete_cf("msitest", FALSE), "File not installed\n");
3041
3042     /* Delete the files in the temp (current) folder */
3043     DeleteFile(msifile);
3044     DeleteFile("msitest\\maximus");
3045     RemoveDirectory("msitest");
3046 }
3047
3048 static void test_cabisextracted(void)
3049 {
3050     UINT r;
3051
3052     CreateDirectoryA("msitest", NULL);
3053     create_file("msitest\\gaius", 500);
3054     create_file("maximus", 500);
3055     create_file("augustus", 500);
3056     create_file("caesar", 500);
3057
3058     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
3059     create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
3060     create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
3061
3062     create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
3063
3064     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3065
3066     r = MsiInstallProductA(msifile, NULL);
3067     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3068     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3069     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3070     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
3071     ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
3072     ok(delete_pf("msitest", FALSE), "File not installed\n");
3073
3074     /* Delete the files in the temp (current) folder */
3075     delete_cab_files();
3076     DeleteFile(msifile);
3077     DeleteFile("maximus");
3078     DeleteFile("augustus");
3079     DeleteFile("caesar");
3080     DeleteFile("msitest\\gaius");
3081     RemoveDirectory("msitest");
3082 }
3083
3084 static void test_concurrentinstall(void)
3085 {
3086     UINT r;
3087     CHAR path[MAX_PATH];
3088
3089     CreateDirectoryA("msitest", NULL);
3090     CreateDirectoryA("msitest\\msitest", NULL);
3091     create_file("msitest\\maximus", 500);
3092     create_file("msitest\\msitest\\augustus", 500);
3093
3094     create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
3095
3096     lstrcpyA(path, CURR_DIR);
3097     lstrcatA(path, "\\msitest\\concurrent.msi");
3098     create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
3099
3100     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3101
3102     r = MsiInstallProductA(msifile, NULL);
3103     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3104     if (!delete_pf("msitest\\augustus", TRUE))
3105         trace("concurrent installs not supported\n");
3106     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3107     ok(delete_pf("msitest", FALSE), "File not installed\n");
3108
3109     DeleteFile(path);
3110
3111     r = MsiInstallProductA(msifile, NULL);
3112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3113     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3114     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3115     ok(delete_pf("msitest", FALSE), "File not installed\n");
3116
3117     DeleteFile(msifile);
3118     DeleteFile("msitest\\msitest\\augustus");
3119     DeleteFile("msitest\\maximus");
3120     RemoveDirectory("msitest\\msitest");
3121     RemoveDirectory("msitest");
3122 }
3123
3124 static void test_setpropertyfolder(void)
3125 {
3126     UINT r;
3127     CHAR path[MAX_PATH];
3128     DWORD attr;
3129
3130     lstrcpyA(path, PROG_FILES_DIR);
3131     lstrcatA(path, "\\msitest\\added");
3132
3133     CreateDirectoryA("msitest", NULL);
3134     create_file("msitest\\maximus", 500);
3135
3136     create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
3137
3138     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3139
3140     r = MsiInstallProductA(msifile, NULL);
3141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3142     attr = GetFileAttributesA(path);
3143     if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
3144     {
3145         ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
3146         ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
3147         ok(delete_pf("msitest", FALSE), "File not installed\n");
3148     }
3149     else
3150     {
3151         trace("changing folder property not supported\n");
3152         ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3153         ok(delete_pf("msitest", FALSE), "File not installed\n");
3154     }
3155
3156     /* Delete the files in the temp (current) folder */
3157     DeleteFile(msifile);
3158     DeleteFile("msitest\\maximus");
3159     RemoveDirectory("msitest");
3160 }
3161
3162 static BOOL file_exists(LPCSTR file)
3163 {
3164     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
3165 }
3166
3167 static BOOL pf_exists(LPCSTR file)
3168 {
3169     CHAR path[MAX_PATH];
3170
3171     lstrcpyA(path, PROG_FILES_DIR);
3172     lstrcatA(path, "\\");
3173     lstrcatA(path, file);
3174
3175     return file_exists(path);
3176 }
3177
3178 static void delete_pfmsitest_files(void)
3179 {
3180     SHFILEOPSTRUCT shfl;
3181     CHAR path[MAX_PATH+11];
3182
3183     lstrcpyA(path, PROG_FILES_DIR);
3184     lstrcatA(path, "\\msitest\\*");
3185     path[strlen(path) + 1] = '\0';
3186
3187     shfl.hwnd = NULL;
3188     shfl.wFunc = FO_DELETE;
3189     shfl.pFrom = path;
3190     shfl.pTo = NULL;
3191     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
3192
3193     SHFileOperation(&shfl);
3194
3195     lstrcpyA(path, PROG_FILES_DIR);
3196     lstrcatA(path, "\\msitest");
3197     RemoveDirectoryA(path);
3198 }
3199
3200 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
3201 {
3202     char val[MAX_PATH];
3203     DWORD size, type;
3204     LONG res;
3205
3206     size = MAX_PATH;
3207     val[0] = '\0';
3208     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
3209
3210     if (res != ERROR_SUCCESS ||
3211         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
3212     {
3213         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
3214         return;
3215     }
3216
3217     if (!expected)
3218         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
3219     else
3220     {
3221         if (bcase)
3222             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
3223         else
3224             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
3225     }
3226 }
3227
3228 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
3229 {
3230     DWORD val, size, type;
3231     LONG res;
3232
3233     size = sizeof(DWORD);
3234     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
3235
3236     if (res != ERROR_SUCCESS || type != REG_DWORD)
3237     {
3238         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
3239         return;
3240     }
3241
3242     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
3243 }
3244
3245 static void check_reg_dword2(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD line)
3246 {
3247     DWORD val, size, type;
3248     LONG res;
3249
3250     size = sizeof(DWORD);
3251     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
3252
3253     if (res != ERROR_SUCCESS || type != REG_DWORD)
3254     {
3255         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
3256         return;
3257     }
3258
3259     ok_(__FILE__, line)(val == expected1 || val == expected2, "Expected %d or %d, got %d\n", expected1, expected2, val);
3260 }
3261
3262 static void check_reg_dword3(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3, DWORD line)
3263 {
3264     DWORD val, size, type;
3265     LONG res;
3266
3267     size = sizeof(DWORD);
3268     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
3269
3270     if (res != ERROR_SUCCESS || type != REG_DWORD)
3271     {
3272         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
3273         return;
3274     }
3275
3276     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3,
3277                         "Expected %d, %d or %d, got %d\n", expected1, expected2, expected3, val);
3278 }
3279
3280 #define CHECK_REG_STR(prodkey, name, expected) \
3281     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
3282
3283 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
3284     check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
3285     RegDeleteValueA(prodkey, name);
3286
3287 #define CHECK_REG_ISTR(prodkey, name, expected) \
3288     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
3289
3290 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
3291     check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
3292     RegDeleteValueA(prodkey, name);
3293
3294 #define CHECK_REG_DWORD(prodkey, name, expected) \
3295     check_reg_dword(prodkey, name, expected, __LINE__);
3296
3297 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
3298     check_reg_dword(prodkey, name, expected, __LINE__); \
3299     RegDeleteValueA(prodkey, name);
3300
3301 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
3302     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
3303
3304 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
3305     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
3306     RegDeleteValueA(prodkey, name);
3307
3308 #define CHECK_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
3309     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__);
3310
3311 #define CHECK_DEL_REG_DWORD3(prodkey, name, expected1, expected2, expected3) \
3312     check_reg_dword3(prodkey, name, expected1, expected2, expected3, __LINE__); \
3313     RegDeleteValueA(prodkey, name);
3314
3315 static void get_date_str(LPSTR date)
3316 {
3317     SYSTEMTIME systime;
3318
3319     static const char date_fmt[] = "%d%02d%02d";
3320     GetLocalTime(&systime);
3321     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
3322 }
3323
3324 static void test_publish_registerproduct(void)
3325 {
3326     UINT r;
3327     LONG res;
3328     HKEY hkey;
3329     HKEY props, usage;
3330     LPSTR usersid;
3331     char date[MAX_PATH];
3332     char temp[MAX_PATH];
3333     char keypath[MAX_PATH];
3334
3335     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3336                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3337     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
3338                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3339     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
3340                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
3341     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
3342                                     "\\51AAE0C44620A5E4788506E91F249BD2";
3343
3344     if (!get_user_sid(&usersid))
3345         return;
3346
3347     get_date_str(date);
3348     GetTempPath(MAX_PATH, temp);
3349
3350     CreateDirectoryA("msitest", NULL);
3351     create_file("msitest\\maximus", 500);
3352
3353     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3354
3355     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3356
3357     /* RegisterProduct */
3358     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
3359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3360     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3361     ok(delete_pf("msitest", FALSE), "File not installed\n");
3362
3363     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
3364     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3365
3366     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
3367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3368
3369     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
3370     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
3371     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
3372     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
3373     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3374     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
3375     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3376     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
3377     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
3378     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
3379     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
3380     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
3381     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
3382     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
3383     CHECK_DEL_REG_STR(hkey, "Size", NULL);
3384     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
3385     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
3386     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3387     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3388     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
3389     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
3390     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
3391     todo_wine
3392     {
3393         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
3394     }
3395
3396     RegDeleteKeyA(hkey, "");
3397     RegCloseKey(hkey);
3398
3399     sprintf(keypath, userdata, usersid);
3400     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
3401     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3402
3403     res = RegOpenKeyA(hkey, "InstallProperties", &props);
3404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3405
3406     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
3407     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
3408     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
3409     CHECK_DEL_REG_STR(props, "InstallDate", date);
3410     CHECK_DEL_REG_STR(props, "InstallSource", temp);
3411     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3412     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
3413     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3414     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
3415     CHECK_DEL_REG_STR(props, "Comments", NULL);
3416     CHECK_DEL_REG_STR(props, "Contact", NULL);
3417     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
3418     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
3419     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
3420     CHECK_DEL_REG_STR(props, "Readme", NULL);
3421     CHECK_DEL_REG_STR(props, "Size", NULL);
3422     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
3423     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
3424     CHECK_DEL_REG_DWORD(props, "Language", 1033);
3425     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
3426     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
3427     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
3428     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
3429     todo_wine
3430     {
3431         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
3432     }
3433
3434     RegDeleteKeyA(props, "");
3435     RegCloseKey(props);
3436
3437     res = RegOpenKeyA(hkey, "Usage", &usage);
3438     todo_wine
3439     {
3440         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3441     }
3442
3443     RegDeleteKeyA(usage, "");
3444     RegCloseKey(usage);
3445     RegDeleteKeyA(hkey, "");
3446     RegCloseKey(hkey);
3447
3448     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
3449     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3450
3451     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3452
3453     RegDeleteKeyA(hkey, "");
3454     RegCloseKey(hkey);
3455
3456     /* RegisterProduct, machine */
3457     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
3458     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3459     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3460     ok(delete_pf("msitest", FALSE), "File not installed\n");
3461
3462     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
3463     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3464
3465     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
3466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3467
3468     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
3469     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
3470     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
3471     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
3472     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3473     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
3474     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3475     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
3476     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
3477     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
3478     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
3479     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
3480     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
3481     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
3482     CHECK_DEL_REG_STR(hkey, "Size", NULL);
3483     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
3484     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
3485     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3486     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3487     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
3488     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
3489     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
3490     todo_wine
3491     {
3492         CHECK_DEL_REG_DWORD3(hkey, "EstimatedSize", 12, -12, 4);
3493     }
3494
3495     RegDeleteKeyA(hkey, "");
3496     RegCloseKey(hkey);
3497
3498     sprintf(keypath, userdata, "S-1-5-18");
3499     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
3500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3501
3502     res = RegOpenKeyA(hkey, "InstallProperties", &props);
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
3506     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
3507     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
3508     CHECK_DEL_REG_STR(props, "InstallDate", date);
3509     CHECK_DEL_REG_STR(props, "InstallSource", temp);
3510     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3511     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
3512     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3513     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
3514     CHECK_DEL_REG_STR(props, "Comments", NULL);
3515     CHECK_DEL_REG_STR(props, "Contact", NULL);
3516     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
3517     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
3518     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
3519     CHECK_DEL_REG_STR(props, "Readme", NULL);
3520     CHECK_DEL_REG_STR(props, "Size", NULL);
3521     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
3522     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
3523     CHECK_DEL_REG_DWORD(props, "Language", 1033);
3524     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
3525     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
3526     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
3527     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
3528     todo_wine
3529     {
3530         CHECK_DEL_REG_DWORD3(props, "EstimatedSize", 12, -12, 4);
3531     }
3532
3533     RegDeleteKeyA(props, "");
3534     RegCloseKey(props);
3535
3536     res = RegOpenKeyA(hkey, "Usage", &usage);
3537     todo_wine
3538     {
3539         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3540     }
3541
3542     RegDeleteKeyA(usage, "");
3543     RegCloseKey(usage);
3544     RegDeleteKeyA(hkey, "");
3545     RegCloseKey(hkey);
3546
3547     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
3548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3549
3550     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3551
3552     RegDeleteKeyA(hkey, "");
3553     RegCloseKey(hkey);
3554
3555     DeleteFile(msifile);
3556     DeleteFile("msitest\\maximus");
3557     RemoveDirectory("msitest");
3558     HeapFree(GetProcessHeap(), 0, usersid);
3559 }
3560
3561 static void test_publish_publishproduct(void)
3562 {
3563     UINT r;
3564     LONG res;
3565     LPSTR usersid;
3566     HKEY sourcelist, net, props;
3567     HKEY hkey, patches, media;
3568     CHAR keypath[MAX_PATH];
3569     CHAR temp[MAX_PATH];
3570     CHAR path[MAX_PATH];
3571
3572     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3573                                    "\\Installer\\UserData\\%s\\Products"
3574                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3575     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
3576                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3577     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
3578                                      "\\51AAE0C44620A5E4788506E91F249BD2";
3579     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3580                                   "\\Installer\\Products"
3581                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3582     static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3583     static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
3584
3585     if (!get_user_sid(&usersid))
3586         return;
3587
3588     GetTempPath(MAX_PATH, temp);
3589
3590     CreateDirectoryA("msitest", NULL);
3591     create_file("msitest\\maximus", 500);
3592
3593     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3594
3595     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3596
3597     /* PublishProduct, current user */
3598     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3599     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3600     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3601     ok(delete_pf("msitest", FALSE), "File not installed\n");
3602
3603     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
3604     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3605
3606     sprintf(keypath, prodpath, usersid);
3607     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
3608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3609
3610     res = RegOpenKeyA(hkey, "InstallProperties", &props);
3611     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3612
3613     res = RegOpenKeyA(hkey, "Patches", &patches);
3614     todo_wine
3615     {
3616         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3617
3618         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
3619     }
3620
3621     RegDeleteKeyA(patches, "");
3622     RegCloseKey(patches);
3623     RegDeleteKeyA(hkey, "");
3624     RegCloseKey(hkey);
3625
3626     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
3627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3628
3629     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
3630     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
3631     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3632     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3633     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
3634     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
3635     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
3636     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
3637     CHECK_DEL_REG_STR(hkey, "Clients", ":");
3638
3639     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
3640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3641
3642     lstrcpyA(path, "n;1;");
3643     lstrcatA(path, temp);
3644     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
3645     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
3646
3647     res = RegOpenKeyA(sourcelist, "Net", &net);
3648     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3649
3650     CHECK_DEL_REG_STR(net, "1", temp);
3651
3652     RegDeleteKeyA(net, "");
3653     RegCloseKey(net);
3654
3655     res = RegOpenKeyA(sourcelist, "Media", &media);
3656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3657
3658     CHECK_DEL_REG_STR(media, "1", "DISK1;");
3659
3660     RegDeleteKeyA(media, "");
3661     RegCloseKey(media);
3662     RegDeleteKeyA(sourcelist, "");
3663     RegCloseKey(sourcelist);
3664     RegDeleteKeyA(hkey, "");
3665     RegCloseKey(hkey);
3666
3667     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
3668     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3669
3670     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3671
3672     RegDeleteKeyA(hkey, "");
3673     RegCloseKey(hkey);
3674
3675     /* PublishProduct, machine */
3676     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
3677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3678     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3679     ok(delete_pf("msitest", FALSE), "File not installed\n");
3680
3681     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
3682     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3683
3684     sprintf(keypath, prodpath, "S-1-5-18");
3685     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
3686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3687
3688     res = RegOpenKeyA(hkey, "InstallProperties", &props);
3689     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3690
3691     res = RegOpenKeyA(hkey, "Patches", &patches);
3692     todo_wine
3693     {
3694         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3695
3696         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
3697     }
3698
3699     RegDeleteKeyA(patches, "");
3700     RegCloseKey(patches);
3701     RegDeleteKeyA(hkey, "");
3702     RegCloseKey(hkey);
3703
3704     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
3705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3706
3707     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
3708     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
3709     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3710     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3711     CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
3712     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
3713     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
3714     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
3715     CHECK_DEL_REG_STR(hkey, "Clients", ":");
3716
3717     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
3718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3719
3720     lstrcpyA(path, "n;1;");
3721     lstrcatA(path, temp);
3722     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
3723     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
3724
3725     res = RegOpenKeyA(sourcelist, "Net", &net);
3726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3727
3728     CHECK_DEL_REG_STR(net, "1", temp);
3729
3730     RegDeleteKeyA(net, "");
3731     RegCloseKey(net);
3732
3733     res = RegOpenKeyA(sourcelist, "Media", &media);
3734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3735
3736     CHECK_DEL_REG_STR(media, "1", "DISK1;");
3737
3738     RegDeleteKeyA(media, "");
3739     RegCloseKey(media);
3740     RegDeleteKeyA(sourcelist, "");
3741     RegCloseKey(sourcelist);
3742     RegDeleteKeyA(hkey, "");
3743     RegCloseKey(hkey);
3744
3745     res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
3746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3747
3748     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3749
3750     RegDeleteKeyA(hkey, "");
3751     RegCloseKey(hkey);
3752
3753     DeleteFile(msifile);
3754     DeleteFile("msitest\\maximus");
3755     RemoveDirectory("msitest");
3756     HeapFree(GetProcessHeap(), 0, usersid);
3757 }
3758
3759 static void test_publish_publishfeatures(void)
3760 {
3761     UINT r;
3762     LONG res;
3763     HKEY hkey;
3764     LPSTR usersid;
3765     CHAR keypath[MAX_PATH];
3766
3767     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
3768                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3769     static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3770                                  "\\Installer\\UserData\\%s\\Products"
3771                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
3772     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3773                                   "\\Installer\\Features";
3774     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
3775                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3776
3777     if (!get_user_sid(&usersid))
3778         return;
3779
3780     CreateDirectoryA("msitest", NULL);
3781     create_file("msitest\\maximus", 500);
3782
3783     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3784
3785     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3786
3787     /* PublishFeatures, current user */
3788     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3789     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3790     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3791     ok(delete_pf("msitest", FALSE), "File not installed\n");
3792
3793     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
3794     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3795
3796     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
3797     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3798
3799     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3801
3802     CHECK_REG_STR(hkey, "feature", "");
3803     CHECK_REG_STR(hkey, "montecristo", "");
3804
3805     RegDeleteValueA(hkey, "feature");
3806     RegDeleteValueA(hkey, "montecristo");
3807     RegDeleteKeyA(hkey, "");
3808     RegCloseKey(hkey);
3809
3810     sprintf(keypath, udpath, usersid);
3811     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
3812     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3813
3814     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3815     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3816
3817     RegDeleteValueA(hkey, "feature");
3818     RegDeleteValueA(hkey, "montecristo");
3819     RegDeleteKeyA(hkey, "");
3820     RegCloseKey(hkey);
3821
3822     /* PublishFeatures, machine */
3823     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
3824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3825     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3826     ok(delete_pf("msitest", FALSE), "File not installed\n");
3827
3828     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
3829     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3830
3831     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3832     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3833
3834     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
3835     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3836
3837     CHECK_REG_STR(hkey, "feature", "");
3838     CHECK_REG_STR(hkey, "montecristo", "");
3839
3840     RegDeleteValueA(hkey, "feature");
3841     RegDeleteValueA(hkey, "montecristo");
3842     RegDeleteKeyA(hkey, "");
3843     RegCloseKey(hkey);
3844
3845     sprintf(keypath, udpath, "S-1-5-18");
3846     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
3847     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3848
3849     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3850     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3851
3852     RegDeleteValueA(hkey, "feature");
3853     RegDeleteValueA(hkey, "montecristo");
3854     RegDeleteKeyA(hkey, "");
3855     RegCloseKey(hkey);
3856
3857     DeleteFile(msifile);
3858     DeleteFile("msitest\\maximus");
3859     RemoveDirectory("msitest");
3860     HeapFree(GetProcessHeap(), 0, usersid);
3861 }
3862
3863 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
3864 {
3865     DWORD len = 0;
3866     LPSTR val;
3867     LONG r;
3868
3869     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
3870     if (r != ERROR_SUCCESS)
3871         return NULL;
3872
3873     len += sizeof (WCHAR);
3874     val = HeapAlloc(GetProcessHeap(), 0, len);
3875     if (!val) return NULL;
3876     val[0] = 0;
3877     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
3878     return val;
3879 }
3880
3881 static void get_owner_company(LPSTR *owner, LPSTR *company)
3882 {
3883     LONG res;
3884     HKEY hkey;
3885
3886     *owner = *company = NULL;
3887
3888     res = RegOpenKeyA(HKEY_CURRENT_USER,
3889                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
3890     if (res == ERROR_SUCCESS)
3891     {
3892         *owner = reg_get_val_str(hkey, "DefName");
3893         *company = reg_get_val_str(hkey, "DefCompany");
3894         RegCloseKey(hkey);
3895     }
3896
3897     if (!*owner || !*company)
3898     {
3899         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
3900                           "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
3901         if (res == ERROR_SUCCESS)
3902         {
3903             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3904             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3905             RegCloseKey(hkey);
3906         }
3907     }
3908
3909     if (!*owner || !*company)
3910     {
3911         res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
3912                           "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
3913         if (res == ERROR_SUCCESS)
3914         {
3915             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3916             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3917             RegCloseKey(hkey);
3918         }
3919     }
3920 }
3921
3922 static void test_publish_registeruser(void)
3923 {
3924     UINT r;
3925     LONG res;
3926     HKEY props;
3927     LPSTR usersid;
3928     LPSTR owner, company;
3929     CHAR keypath[MAX_PATH];
3930
3931     static const CHAR keyfmt[] =
3932         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3933         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
3934
3935     if (!get_user_sid(&usersid))
3936         return;
3937
3938     get_owner_company(&owner, &company);
3939
3940     CreateDirectoryA("msitest", NULL);
3941     create_file("msitest\\maximus", 500);
3942
3943     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3944
3945     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3946
3947     /* RegisterUser, per-user */
3948     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
3949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3950     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3951     ok(delete_pf("msitest", FALSE), "File not installed\n");
3952
3953     sprintf(keypath, keyfmt, usersid);
3954
3955     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
3956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3957
3958     CHECK_REG_STR(props, "ProductID", "none");
3959     CHECK_REG_STR(props, "RegCompany", company);
3960     CHECK_REG_STR(props, "RegOwner", owner);
3961
3962     RegDeleteValueA(props, "ProductID");
3963     RegDeleteValueA(props, "RegCompany");
3964     RegDeleteValueA(props, "RegOwner");
3965     RegDeleteKeyA(props, "");
3966     RegCloseKey(props);
3967
3968     /* RegisterUser, machine */
3969     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
3970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3971     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3972     ok(delete_pf("msitest", FALSE), "File not installed\n");
3973
3974     sprintf(keypath, keyfmt, "S-1-5-18");
3975
3976     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
3977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3978
3979     CHECK_REG_STR(props, "ProductID", "none");
3980     CHECK_REG_STR(props, "RegCompany", company);
3981     CHECK_REG_STR(props, "RegOwner", owner);
3982
3983     RegDeleteValueA(props, "ProductID");
3984     RegDeleteValueA(props, "RegCompany");
3985     RegDeleteValueA(props, "RegOwner");
3986     RegDeleteKeyA(props, "");
3987     RegCloseKey(props);
3988
3989     HeapFree(GetProcessHeap(), 0, company);
3990     HeapFree(GetProcessHeap(), 0, owner);
3991
3992     DeleteFile(msifile);
3993     DeleteFile("msitest\\maximus");
3994     RemoveDirectory("msitest");
3995     LocalFree(usersid);
3996 }
3997
3998 static void test_publish_processcomponents(void)
3999 {
4000     UINT r;
4001     LONG res;
4002     DWORD size;
4003     HKEY comp, hkey;
4004     LPSTR usersid;
4005     CHAR val[MAX_PATH];
4006     CHAR keypath[MAX_PATH];
4007     CHAR program_files_maximus[MAX_PATH];
4008
4009     static const CHAR keyfmt[] =
4010         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
4011         "UserData\\%s\\Components\\%s";
4012     static const CHAR compkey[] =
4013         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
4014
4015     if (!get_user_sid(&usersid))
4016         return;
4017
4018     CreateDirectoryA("msitest", NULL);
4019     create_file("msitest\\maximus", 500);
4020
4021     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
4022
4023     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4024
4025     /* ProcessComponents, per-user */
4026     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4027     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4028     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4029     ok(delete_pf("msitest", FALSE), "File not installed\n");
4030
4031     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
4032
4033     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4035
4036     size = MAX_PATH;
4037     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4038                            NULL, NULL, (LPBYTE)val, &size);
4039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4040
4041     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
4042     lstrcatA(program_files_maximus,"\\msitest\\maximus");
4043
4044     ok(!lstrcmpiA(val, program_files_maximus),
4045        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
4046
4047     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4048     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4049
4050     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4051     RegDeleteKeyA(comp, "");
4052     RegCloseKey(comp);
4053
4054     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
4055
4056     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4057     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4058
4059     size = MAX_PATH;
4060     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4061                            NULL, NULL, (LPBYTE)val, &size);
4062     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4063     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
4064        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
4065
4066     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4067     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4068
4069     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4070     RegDeleteKeyA(comp, "");
4071     RegCloseKey(comp);
4072
4073     /* ProcessComponents, machine */
4074     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
4075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4076     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4077     ok(delete_pf("msitest", FALSE), "File not installed\n");
4078
4079     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
4080
4081     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4083
4084     size = MAX_PATH;
4085     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4086                            NULL, NULL, (LPBYTE)val, &size);
4087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4088     ok(!lstrcmpiA(val, program_files_maximus),
4089        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
4090
4091     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4092     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4093
4094     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4095     RegDeleteKeyA(comp, "");
4096     RegCloseKey(comp);
4097
4098     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
4099
4100     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
4101     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4102
4103     size = MAX_PATH;
4104     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
4105                            NULL, NULL, (LPBYTE)val, &size);
4106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4107     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
4108        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
4109
4110     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
4111     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4112
4113     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
4114     RegDeleteKeyA(comp, "");
4115     RegCloseKey(comp);
4116
4117     DeleteFile(msifile);
4118     DeleteFile("msitest\\maximus");
4119     RemoveDirectory("msitest");
4120     LocalFree(usersid);
4121 }
4122
4123 static void test_publish(void)
4124 {
4125     UINT r;
4126     LONG res;
4127     HKEY uninstall, prodkey;
4128     INSTALLSTATE state;
4129     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4130     char date[MAX_PATH];
4131     char temp[MAX_PATH];
4132
4133     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
4134
4135     if (!pMsiQueryComponentStateA)
4136     {
4137         win_skip("MsiQueryComponentStateA is not available\n");
4138         return;
4139     }
4140
4141     get_date_str(date);
4142     GetTempPath(MAX_PATH, temp);
4143
4144     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
4145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4146
4147     CreateDirectoryA("msitest", NULL);
4148     create_file("msitest\\maximus", 500);
4149
4150     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4151
4152     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4153
4154     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4155     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4156
4157     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4158     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4159
4160     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4161     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4162
4163     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4164                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4165     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4166     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4167
4168     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4169     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4170
4171     /* nothing published */
4172     r = MsiInstallProductA(msifile, NULL);
4173     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4174     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4175     ok(pf_exists("msitest"), "File not installed\n");
4176
4177     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4178     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4179
4180     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4181     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4182
4183     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4184     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4185
4186     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4187                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4188     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4189     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4190
4191     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4192     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4193
4194     /* PublishProduct and RegisterProduct */
4195     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
4196     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4197     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4198     ok(pf_exists("msitest"), "File not installed\n");
4199
4200     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4201     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4202
4203     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4204     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4205
4206     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4207     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4208
4209     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4210                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4211     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4212     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4213
4214     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4216
4217     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4218     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4219     CHECK_REG_STR(prodkey, "InstallDate", date);
4220     CHECK_REG_STR(prodkey, "InstallSource", temp);
4221     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4222     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4223     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4224     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4225     CHECK_REG_STR(prodkey, "Comments", NULL);
4226     CHECK_REG_STR(prodkey, "Contact", NULL);
4227     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4228     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4229     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4230     CHECK_REG_STR(prodkey, "Readme", NULL);
4231     CHECK_REG_STR(prodkey, "Size", NULL);
4232     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4233     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4234     CHECK_REG_DWORD(prodkey, "Language", 1033);
4235     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4236     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4237     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4238     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4239     todo_wine
4240     {
4241         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4242     }
4243
4244     RegCloseKey(prodkey);
4245
4246     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4248     ok(pf_exists("msitest\\maximus"), "File deleted\n");
4249     ok(pf_exists("msitest"), "File deleted\n");
4250
4251     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4252     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4253
4254     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4255     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4256
4257     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4258     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4259
4260     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4261                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4262     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4263     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4264
4265     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4266     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4267
4268     /* complete install */
4269     r = MsiInstallProductA(msifile, "FULL=1");
4270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4271     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4272     ok(pf_exists("msitest"), "File not installed\n");
4273
4274     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4275     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4276
4277     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4278     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4279
4280     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4281     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4282
4283     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4284                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4286     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4287
4288     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4290
4291     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4292     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4293     CHECK_REG_STR(prodkey, "InstallDate", date);
4294     CHECK_REG_STR(prodkey, "InstallSource", temp);
4295     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4296     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4297     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4298     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4299     CHECK_REG_STR(prodkey, "Comments", NULL);
4300     CHECK_REG_STR(prodkey, "Contact", NULL);
4301     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4302     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4303     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4304     CHECK_REG_STR(prodkey, "Readme", NULL);
4305     CHECK_REG_STR(prodkey, "Size", NULL);
4306     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4307     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4308     CHECK_REG_DWORD(prodkey, "Language", 1033);
4309     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4310     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4311     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4312     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4313     todo_wine
4314     {
4315         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4316     }
4317
4318     RegCloseKey(prodkey);
4319
4320     /* no UnpublishFeatures */
4321     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4322     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4323     ok(!pf_exists("msitest\\maximus"), "File deleted\n");
4324     todo_wine
4325     {
4326         ok(!pf_exists("msitest"), "File deleted\n");
4327     }
4328
4329     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4330     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4331
4332     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4333     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4334
4335     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4336     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4337
4338     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4339                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4340     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4341     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4342
4343     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4344     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4345
4346     /* complete install */
4347     r = MsiInstallProductA(msifile, "FULL=1");
4348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4349     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4350     ok(pf_exists("msitest"), "File not installed\n");
4351
4352     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4353     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4354
4355     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4356     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4357
4358     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4359     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4360
4361     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4362                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4364     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4365
4366     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4368
4369     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4370     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4371     CHECK_REG_STR(prodkey, "InstallDate", date);
4372     CHECK_REG_STR(prodkey, "InstallSource", temp);
4373     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4374     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4375     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4376     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4377     CHECK_REG_STR(prodkey, "Comments", NULL);
4378     CHECK_REG_STR(prodkey, "Contact", NULL);
4379     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4380     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4381     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4382     CHECK_REG_STR(prodkey, "Readme", NULL);
4383     CHECK_REG_STR(prodkey, "Size", NULL);
4384     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4385     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4386     CHECK_REG_DWORD(prodkey, "Language", 1033);
4387     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4388     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4389     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4390     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4391     todo_wine
4392     {
4393         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4394     }
4395
4396     RegCloseKey(prodkey);
4397
4398     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
4399     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
4400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4401     todo_wine ok(pf_exists("msitest\\maximus"), "File deleted\n");
4402     ok(pf_exists("msitest"), "File deleted\n");
4403
4404     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4405     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4406
4407     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4408     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4409
4410     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4411     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4412
4413     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4414                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4416     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4417
4418     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4420
4421     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4422     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4423     CHECK_REG_STR(prodkey, "InstallDate", date);
4424     CHECK_REG_STR(prodkey, "InstallSource", temp);
4425     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4426     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4427     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4428     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4429     CHECK_REG_STR(prodkey, "Comments", NULL);
4430     CHECK_REG_STR(prodkey, "Contact", NULL);
4431     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4432     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4433     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4434     CHECK_REG_STR(prodkey, "Readme", NULL);
4435     CHECK_REG_STR(prodkey, "Size", NULL);
4436     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4437     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4438     CHECK_REG_DWORD(prodkey, "Language", 1033);
4439     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4440     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4441     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4442     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4443     todo_wine
4444     {
4445         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4446     }
4447
4448     RegCloseKey(prodkey);
4449
4450     /* complete install */
4451     r = MsiInstallProductA(msifile, "FULL=1");
4452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4453     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4454     ok(pf_exists("msitest"), "File not installed\n");
4455
4456     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4457     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4458
4459     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4460     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4461
4462     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4463     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4464
4465     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4466                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4467     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4468     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4469
4470     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4472
4473     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4474     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4475     CHECK_REG_STR(prodkey, "InstallDate", date);
4476     CHECK_REG_STR(prodkey, "InstallSource", temp);
4477     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4478     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4479     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4480     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4481     CHECK_REG_STR(prodkey, "Comments", NULL);
4482     CHECK_REG_STR(prodkey, "Contact", NULL);
4483     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4484     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4485     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4486     CHECK_REG_STR(prodkey, "Readme", NULL);
4487     CHECK_REG_STR(prodkey, "Size", NULL);
4488     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4489     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4490     CHECK_REG_DWORD(prodkey, "Language", 1033);
4491     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4492     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4493     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4494     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4495     todo_wine
4496     {
4497         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -20);
4498     }
4499
4500     RegCloseKey(prodkey);
4501
4502     /* UnpublishFeatures, both features removed */
4503     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
4504     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4505     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4506     todo_wine
4507     {
4508         ok(!pf_exists("msitest"), "File not deleted\n");
4509     }
4510
4511     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4512     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4513
4514     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4515     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4516
4517     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4518     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4519
4520     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4521                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4522     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4523     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4524
4525     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4526     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4527
4528     /* complete install */
4529     r = MsiInstallProductA(msifile, "FULL=1");
4530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4531     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4532     ok(pf_exists("msitest"), "File not installed\n");
4533
4534     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4535     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4536
4537     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4538     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4539
4540     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4541     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4542
4543     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4544                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4546     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4547
4548     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4550
4551     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4552     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4553     CHECK_REG_STR(prodkey, "InstallDate", date);
4554     CHECK_REG_STR(prodkey, "InstallSource", temp);
4555     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4556     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4557     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4558     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4559     CHECK_REG_STR(prodkey, "Comments", NULL);
4560     CHECK_REG_STR(prodkey, "Contact", NULL);
4561     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4562     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4563     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4564     CHECK_REG_STR(prodkey, "Readme", NULL);
4565     CHECK_REG_STR(prodkey, "Size", NULL);
4566     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4567     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4568     CHECK_REG_DWORD(prodkey, "Language", 1033);
4569     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4570     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4571     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4572     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4573     todo_wine
4574     {
4575         CHECK_REG_DWORD2(prodkey, "EstimatedSize", 12, -12);
4576     }
4577
4578     RegCloseKey(prodkey);
4579
4580     /* complete uninstall */
4581     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4583     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4584     todo_wine
4585     {
4586         ok(!pf_exists("msitest"), "File not deleted\n");
4587     }
4588
4589     state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4590     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4591
4592     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
4593     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4594
4595     state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
4596     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4597
4598     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4599                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4600     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4601     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4602
4603     res = RegOpenKeyA(uninstall, prodcode, &prodkey);
4604     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4605
4606     /* make sure 'Program Files\msitest' is removed */
4607     delete_pfmsitest_files();
4608
4609     RegCloseKey(uninstall);
4610     DeleteFile(msifile);
4611     DeleteFile("msitest\\maximus");
4612     RemoveDirectory("msitest");
4613 }
4614
4615 static void test_publishsourcelist(void)
4616 {
4617     UINT r;
4618     DWORD size;
4619     CHAR value[MAX_PATH];
4620     CHAR path[MAX_PATH];
4621     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4622
4623     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
4624     {
4625         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
4626         return;
4627     }
4628
4629     CreateDirectoryA("msitest", NULL);
4630     create_file("msitest\\maximus", 500);
4631
4632     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4633
4634     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4635
4636     r = MsiInstallProductA(msifile, NULL);
4637     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4638     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4639     ok(pf_exists("msitest"), "File not installed\n");
4640
4641     /* nothing published */
4642     size = MAX_PATH;
4643     lstrcpyA(value, "aaa");
4644     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4645                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4646     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4647     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4648     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4649
4650     size = MAX_PATH;
4651     lstrcpyA(value, "aaa");
4652     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4653                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4654     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4655     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4656     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4657
4658     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4659     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4660     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4661     ok(pf_exists("msitest"), "File not installed\n");
4662
4663     /* after RegisterProduct */
4664     size = MAX_PATH;
4665     lstrcpyA(value, "aaa");
4666     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4667                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4668     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4669     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4670     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4671
4672     size = MAX_PATH;
4673     lstrcpyA(value, "aaa");
4674     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4675                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4676     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4677     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4678     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4679
4680     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4681     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4682     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4683     ok(pf_exists("msitest"), "File not installed\n");
4684
4685     /* after ProcessComponents */
4686     size = MAX_PATH;
4687     lstrcpyA(value, "aaa");
4688     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4689                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4690     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4691     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4692     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4693
4694     size = MAX_PATH;
4695     lstrcpyA(value, "aaa");
4696     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4697                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4698     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4699     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4700     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4701
4702     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4704     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4705     ok(pf_exists("msitest"), "File not installed\n");
4706
4707     /* after PublishFeatures */
4708     size = MAX_PATH;
4709     lstrcpyA(value, "aaa");
4710     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4711                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4712     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4713     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4714     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4715
4716     size = MAX_PATH;
4717     lstrcpyA(value, "aaa");
4718     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4719                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4720     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4721     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4722     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4723
4724     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4726     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4727     ok(pf_exists("msitest"), "File not installed\n");
4728
4729     /* after PublishProduct */
4730     size = MAX_PATH;
4731     lstrcpyA(value, "aaa");
4732     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4733                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4735     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
4736     ok(size == 11, "Expected 11, got %d\n", size);
4737
4738     size = MAX_PATH;
4739     lstrcpyA(value, "aaa");
4740     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4741                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
4742     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4744     ok(size == 0, "Expected 0, got %d\n", size);
4745
4746     size = MAX_PATH;
4747     lstrcpyA(value, "aaa");
4748     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4749                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
4750     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4751     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4752     ok(size == 0, "Expected 0, got %d\n", size);
4753
4754     lstrcpyA(path, CURR_DIR);
4755     lstrcatA(path, "\\");
4756
4757     size = MAX_PATH;
4758     lstrcpyA(value, "aaa");
4759     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4760                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4762     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4763     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4764
4765     size = MAX_PATH;
4766     lstrcpyA(value, "aaa");
4767     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4768                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
4769     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4770     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
4771     ok(size == 1, "Expected 1, got %d\n", size);
4772
4773     size = MAX_PATH;
4774     lstrcpyA(value, "aaa");
4775     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4776                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4777     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4778     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4779     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4780
4781     size = MAX_PATH;
4782     lstrcpyA(value, "aaa");
4783     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4784                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
4785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4786     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4787     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4788
4789     size = MAX_PATH;
4790     lstrcpyA(value, "aaa");
4791     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4792                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
4793     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4794     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4795     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4796
4797     /* complete uninstall */
4798     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4799     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4800     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4801     todo_wine
4802     {
4803         ok(!pf_exists("msitest"), "File not deleted\n");
4804     }
4805
4806     /* make sure 'Program Files\msitest' is removed */
4807     delete_pfmsitest_files();
4808
4809     DeleteFile(msifile);
4810     DeleteFile("msitest\\maximus");
4811     RemoveDirectory("msitest");
4812 }
4813
4814 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
4815 {
4816     MSIHANDLE hview = 0;
4817     UINT r;
4818
4819     r = MsiDatabaseOpenView(hdb, query, &hview);
4820     if(r != ERROR_SUCCESS)
4821         return r;
4822
4823     r = MsiViewExecute(hview, hrec);
4824     if(r == ERROR_SUCCESS)
4825         r = MsiViewClose(hview);
4826     MsiCloseHandle(hview);
4827     return r;
4828 }
4829
4830 static void set_transform_summary_info(void)
4831 {
4832     UINT r;
4833     MSIHANDLE suminfo = 0;
4834
4835     /* build summary info */
4836     r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
4837     ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
4838
4839     r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
4840     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
4841
4842     r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
4843                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
4844                         "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
4845                         "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
4846     ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
4847
4848     r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
4849     ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
4850
4851     r = MsiSummaryInfoPersist(suminfo);
4852     ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
4853
4854     r = MsiCloseHandle(suminfo);
4855     ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
4856 }
4857
4858 static void generate_transform(void)
4859 {
4860     MSIHANDLE hdb1, hdb2;
4861     LPCSTR query;
4862     UINT r;
4863
4864     /* start with two identical databases */
4865     CopyFile(msifile, msifile2, FALSE);
4866
4867     r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
4868     ok(r == ERROR_SUCCESS , "Failed to create database\n");
4869
4870     r = MsiDatabaseCommit(hdb1);
4871     ok(r == ERROR_SUCCESS , "Failed to commit database\n");
4872
4873     r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
4874     ok(r == ERROR_SUCCESS , "Failed to create database\n");
4875
4876     query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
4877     r = run_query(hdb1, 0, query);
4878     ok(r == ERROR_SUCCESS, "failed to add property\n");
4879
4880     /* database needs to be committed */
4881     MsiDatabaseCommit(hdb1);
4882
4883     r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
4884     ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
4885
4886 #if 0  /* not implemented in wine yet */
4887     r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
4888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4889 #endif
4890
4891     MsiCloseHandle(hdb1);
4892     MsiCloseHandle(hdb2);
4893 }
4894
4895 /* data for generating a transform */
4896
4897 /* tables transform names - encoded as they would be in an msi database file */
4898 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
4899 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
4900 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
4901
4902 /* data in each table */
4903 static const char data1[] = /* _StringData */
4904     "propval";  /* all the strings squashed together */
4905
4906 static const WCHAR data2[] = { /* _StringPool */
4907 /*  len, refs */
4908     0,   0,    /* string 0 ''     */
4909     4,   1,    /* string 1 'prop' */
4910     3,   1,    /* string 2 'val'  */
4911 };
4912
4913 static const WCHAR data3[] = { /* Property */
4914     0x0201, 0x0001, 0x0002,
4915 };
4916
4917 static const struct {
4918     LPCWSTR name;
4919     const void *data;
4920     DWORD size;
4921 } table_transform_data[] =
4922 {
4923     { name1, data1, sizeof data1 - 1 },
4924     { name2, data2, sizeof data2 },
4925     { name3, data3, sizeof data3 },
4926 };
4927
4928 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
4929
4930 static void generate_transform_manual(void)
4931 {
4932     IStorage *stg = NULL;
4933     IStream *stm;
4934     WCHAR name[0x20];
4935     HRESULT r;
4936     DWORD i, count;
4937     const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
4938
4939     const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
4940
4941     MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
4942
4943     r = StgCreateDocfile(name, mode, 0, &stg);
4944     ok(r == S_OK, "failed to create storage\n");
4945     if (!stg)
4946         return;
4947
4948     r = IStorage_SetClass(stg, &CLSID_MsiTransform);
4949     ok(r == S_OK, "failed to set storage type\n");
4950
4951     for (i=0; i<NUM_TRANSFORM_TABLES; i++)
4952     {
4953         r = IStorage_CreateStream(stg, table_transform_data[i].name,
4954                             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4955         if (FAILED(r))
4956         {
4957             ok(0, "failed to create stream %08x\n", r);
4958             continue;
4959         }
4960
4961         r = IStream_Write(stm, table_transform_data[i].data,
4962                           table_transform_data[i].size, &count);
4963         if (FAILED(r) || count != table_transform_data[i].size)
4964             ok(0, "failed to write stream\n");
4965         IStream_Release(stm);
4966     }
4967
4968     IStorage_Release(stg);
4969
4970     set_transform_summary_info();
4971 }
4972
4973 static void test_transformprop(void)
4974 {
4975     UINT r;
4976
4977     CreateDirectoryA("msitest", NULL);
4978     create_file("msitest\\augustus", 500);
4979
4980     create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
4981
4982     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4983
4984     r = MsiInstallProductA(msifile, NULL);
4985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4986     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4987     ok(!delete_pf("msitest", FALSE), "File installed\n");
4988
4989     if (0)
4990         generate_transform();
4991     else
4992         generate_transform_manual();
4993
4994     r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
4995     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4996     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4997     ok(delete_pf("msitest", FALSE), "File not installed\n");
4998
4999     /* Delete the files in the temp (current) folder */
5000     DeleteFile(msifile);
5001     DeleteFile(msifile2);
5002     DeleteFile(mstfile);
5003     DeleteFile("msitest\\augustus");
5004     RemoveDirectory("msitest");
5005 }
5006
5007 static void test_currentworkingdir(void)
5008 {
5009     UINT r;
5010     CHAR drive[MAX_PATH], path[MAX_PATH];
5011     LPSTR ptr;
5012
5013     CreateDirectoryA("msitest", NULL);
5014     create_file("msitest\\augustus", 500);
5015
5016     create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
5017
5018     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5019
5020     CreateDirectoryA("diffdir", NULL);
5021     SetCurrentDirectoryA("diffdir");
5022
5023     sprintf(path, "..\\%s", msifile);
5024     r = MsiInstallProductA(path, NULL);
5025     todo_wine
5026     {
5027         ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
5028         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5029         ok(!delete_pf("msitest", FALSE), "File installed\n");
5030     }
5031
5032     sprintf(path, "%s\\%s", CURR_DIR, msifile);
5033     r = MsiInstallProductA(path, NULL);
5034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5035     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5036     ok(delete_pf("msitest", FALSE), "File not installed\n");
5037
5038     lstrcpyA(drive, CURR_DIR);
5039     drive[2] = '\\';
5040     drive[3] = '\0';
5041     SetCurrentDirectoryA(drive);
5042
5043     lstrcpy(path, CURR_DIR);
5044     if (path[lstrlenA(path) - 1] != '\\')
5045         lstrcatA(path, "\\");
5046     lstrcatA(path, msifile);
5047     ptr = strchr(path, ':');
5048     ptr +=2;
5049
5050     r = MsiInstallProductA(ptr, NULL);
5051     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5052     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5053     ok(delete_pf("msitest", FALSE), "File not installed\n");
5054
5055     SetCurrentDirectoryA(CURR_DIR);
5056
5057     DeleteFile(msifile);
5058     DeleteFile("msitest\\augustus");
5059     RemoveDirectory("msitest");
5060     RemoveDirectory("diffdir");
5061 }
5062
5063 static void set_admin_summary_info(const CHAR *name)
5064 {
5065     MSIHANDLE db, summary;
5066     UINT r;
5067
5068     r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
5069     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5070
5071     r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
5072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5073
5074     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
5075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5076
5077     /* write the summary changes back to the stream */
5078     r = MsiSummaryInfoPersist(summary);
5079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5080
5081     MsiCloseHandle(summary);
5082
5083     r = MsiDatabaseCommit(db);
5084     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5085
5086     MsiCloseHandle(db);
5087 }
5088
5089 static void test_admin(void)
5090 {
5091     UINT r;
5092
5093     CreateDirectoryA("msitest", NULL);
5094     create_file("msitest\\augustus", 500);
5095
5096     create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
5097     set_admin_summary_info(msifile);
5098
5099     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5100
5101     r = MsiInstallProductA(msifile, NULL);
5102     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5103     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5104     ok(!delete_pf("msitest", FALSE), "File installed\n");
5105     ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
5106     ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
5107
5108     r = MsiInstallProductA(msifile, "ACTION=ADMIN");
5109     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5110     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5111     ok(!delete_pf("msitest", FALSE), "File installed\n");
5112     todo_wine
5113     {
5114         ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
5115         ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
5116     }
5117
5118     DeleteFile(msifile);
5119     DeleteFile("msitest\\augustus");
5120     RemoveDirectory("msitest");
5121 }
5122
5123 static void set_admin_property_stream(LPCSTR file)
5124 {
5125     IStorage *stg;
5126     IStream *stm;
5127     WCHAR fileW[MAX_PATH];
5128     HRESULT hr;
5129     DWORD count;
5130     const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
5131
5132     /* AdminProperties */
5133     static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
5134     static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',' ',
5135         'M','y','P','r','o','p','=','4','2',0};
5136
5137     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
5138
5139     hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
5140     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5141     if (!stg)
5142         return;
5143
5144     hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
5145     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5146
5147     hr = IStream_Write(stm, data, sizeof(data), &count);
5148     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
5149
5150     IStream_Release(stm);
5151     IStorage_Release(stg);
5152 }
5153
5154 static void test_adminprops(void)
5155 {
5156     UINT r;
5157
5158     CreateDirectoryA("msitest", NULL);
5159     create_file("msitest\\augustus", 500);
5160
5161     create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
5162     set_admin_summary_info(msifile);
5163     set_admin_property_stream(msifile);
5164
5165     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5166
5167     r = MsiInstallProductA(msifile, NULL);
5168     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5169     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5170     ok(delete_pf("msitest", FALSE), "File installed\n");
5171
5172     DeleteFile(msifile);
5173     DeleteFile("msitest\\augustus");
5174     RemoveDirectory("msitest");
5175 }
5176
5177 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
5178 {
5179     CHAR path[MAX_PATH];
5180
5181     lstrcpyA(path, PROG_FILES_DIR);
5182     lstrcatA(path, "\\");
5183     lstrcatA(path, file);
5184
5185     if (is_file)
5186         create_file_data(path, data, 500);
5187     else
5188         CreateDirectoryA(path, NULL);
5189 }
5190
5191 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
5192
5193 static void test_removefiles(void)
5194 {
5195     UINT r;
5196
5197     CreateDirectoryA("msitest", NULL);
5198     create_file("msitest\\hydrogen", 500);
5199     create_file("msitest\\helium", 500);
5200     create_file("msitest\\lithium", 500);
5201
5202     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
5203
5204     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5205
5206     r = MsiInstallProductA(msifile, NULL);
5207     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5208     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5209     ok(!pf_exists("msitest\\helium"), "File installed\n");
5210     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5211     ok(pf_exists("msitest"), "File not installed\n");
5212
5213     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5215     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
5216     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
5217     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
5218     ok(delete_pf("msitest", FALSE), "File deleted\n");
5219
5220     create_pf("msitest", FALSE);
5221     create_pf("msitest\\hydrogen", TRUE);
5222     create_pf("msitest\\helium", TRUE);
5223     create_pf("msitest\\lithium", TRUE);
5224
5225     r = MsiInstallProductA(msifile, NULL);
5226     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5227     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5228     ok(pf_exists("msitest\\helium"), "File not installed\n");
5229     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5230     ok(pf_exists("msitest"), "File not installed\n");
5231
5232     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5234     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
5235     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
5236     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
5237     ok(delete_pf("msitest", FALSE), "File deleted\n");
5238
5239     create_pf("msitest", FALSE);
5240     create_pf("msitest\\furlong", TRUE);
5241     create_pf("msitest\\firkin", TRUE);
5242     create_pf("msitest\\fortnight", TRUE);
5243     create_pf("msitest\\becquerel", TRUE);
5244     create_pf("msitest\\dioptre", TRUE);
5245     create_pf("msitest\\attoparsec", TRUE);
5246     create_pf("msitest\\storeys", TRUE);
5247     create_pf("msitest\\block", TRUE);
5248     create_pf("msitest\\siriometer", TRUE);
5249     create_pf("msitest\\cabout", FALSE);
5250     create_pf("msitest\\cabout\\blocker", TRUE);
5251
5252     r = MsiInstallProductA(msifile, NULL);
5253     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5254     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
5255     ok(!pf_exists("msitest\\helium"), "File installed\n");
5256     ok(pf_exists("msitest\\lithium"), "File not installed\n");
5257     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
5258     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
5259     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
5260     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
5261     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
5262     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
5263     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
5264     ok(!pf_exists("msitest\\block"), "File not deleted\n");
5265     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
5266     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
5267     ok(pf_exists("msitest"), "File not installed\n");
5268
5269     create_pf("msitest\\furlong", TRUE);
5270     create_pf("msitest\\firkin", TRUE);
5271     create_pf("msitest\\fortnight", TRUE);
5272     create_pf("msitest\\storeys", TRUE);
5273     create_pf("msitest\\block", TRUE);
5274     create_pf("msitest\\siriometer", TRUE);
5275
5276     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5278     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
5279     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
5280     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
5281     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
5282     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
5283     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
5284     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
5285     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
5286     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
5287     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
5288     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
5289     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
5290     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
5291     ok(pf_exists("msitest"), "Directory deleted\n");
5292
5293     r = MsiInstallProductA(msifile, NULL);
5294     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5295     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
5296     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
5297     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
5298     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
5299     ok(pf_exists("msitest"), "Directory deleted\n");
5300
5301     delete_pf("msitest\\cabout\\blocker", TRUE);
5302
5303     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5304     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5305     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
5306     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
5307
5308     DeleteFile(msifile);
5309     DeleteFile("msitest\\hydrogen");
5310     DeleteFile("msitest\\helium");
5311     DeleteFile("msitest\\lithium");
5312     RemoveDirectory("msitest");
5313 }
5314
5315 static void test_movefiles(void)
5316 {
5317     UINT r;
5318     char props[MAX_PATH];
5319
5320     CreateDirectoryA("msitest", NULL);
5321     create_file("msitest\\augustus", 100);
5322     create_file("cameroon", 100);
5323     create_file("djibouti", 100);
5324     create_file("egypt", 100);
5325     create_file("finland", 100);
5326     create_file("gambai", 100);
5327     create_file("honduras", 100);
5328     create_file("msitest\\india", 100);
5329     create_file("japan", 100);
5330     create_file("kenya", 100);
5331     CreateDirectoryA("latvia", NULL);
5332     create_file("nauru", 100);
5333     create_file("peru", 100);
5334     create_file("apple", 100);
5335     create_file("application", 100);
5336     create_file("ape", 100);
5337     create_file("foo", 100);
5338     create_file("fao", 100);
5339     create_file("fbod", 100);
5340     create_file("budding", 100);
5341     create_file("buddy", 100);
5342     create_file("bud", 100);
5343     create_file("bar", 100);
5344     create_file("bur", 100);
5345     create_file("bird", 100);
5346
5347     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
5348
5349     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
5350
5351     /* if the source or dest property is not a full path,
5352      * windows tries to access it as a network resource
5353      */
5354
5355     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
5356             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
5357             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
5358
5359     r = MsiInstallProductA(msifile, props);
5360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5361     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5362     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
5363     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
5364     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
5365     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
5366     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
5367     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
5368     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
5369     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
5370     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
5371     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
5372     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
5373     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
5374     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
5375     /* either apple or application will be moved depending on directory order */
5376     if (!delete_pf("msitest\\apple", TRUE))
5377         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
5378     else
5379         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
5380     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
5381     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
5382     /* either fao or foo will be moved depending on directory order */
5383     if (delete_pf("msitest\\foo", TRUE))
5384         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
5385     else
5386         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
5387     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
5388     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
5389     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
5390     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
5391     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
5392     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
5393     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
5394     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
5395     ok(delete_pf("msitest", FALSE), "File not installed\n");
5396     ok(DeleteFileA("cameroon"), "File moved\n");
5397     ok(!DeleteFileA("djibouti"), "File not moved\n");
5398     ok(DeleteFileA("egypt"), "File moved\n");
5399     ok(DeleteFileA("finland"), "File moved\n");
5400     ok(DeleteFileA("gambai"), "File moved\n");
5401     ok(!DeleteFileA("honduras"), "File not moved\n");
5402     ok(DeleteFileA("msitest\\india"), "File moved\n");
5403     ok(DeleteFileA("japan"), "File moved\n");
5404     ok(!DeleteFileA("kenya"), "File not moved\n");
5405     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
5406     ok(!DeleteFileA("nauru"), "File not moved\n");
5407     ok(!DeleteFileA("peru"), "File not moved\n");
5408     ok(!DeleteFileA("apple"), "File not moved\n");
5409     ok(!DeleteFileA("application"), "File not moved\n");
5410     ok(DeleteFileA("ape"), "File moved\n");
5411     ok(!DeleteFileA("foo"), "File not moved\n");
5412     ok(!DeleteFileA("fao"), "File not moved\n");
5413     ok(DeleteFileA("fbod"), "File moved\n");
5414     ok(!DeleteFileA("budding"), "File not moved\n");
5415     ok(!DeleteFileA("buddy"), "File not moved\n");
5416     ok(DeleteFileA("bud"), "File moved\n");
5417     ok(!DeleteFileA("bar"), "File not moved\n");
5418     ok(!DeleteFileA("bur"), "File not moved\n");
5419     ok(DeleteFileA("bird"), "File moved\n");
5420
5421     DeleteFile("msitest\\augustus");
5422     RemoveDirectory("msitest");
5423     DeleteFile(msifile);
5424 }
5425
5426 static void test_missingcab(void)
5427 {
5428     UINT r;
5429
5430     CreateDirectoryA("msitest", NULL);
5431     create_file("msitest\\augustus", 500);
5432     create_file("maximus", 500);
5433
5434     create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
5435
5436     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5437
5438     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
5439
5440     create_pf("msitest", FALSE);
5441     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
5442
5443     r = MsiInstallProductA(msifile, NULL);
5444     ok(r == ERROR_SUCCESS ||
5445        broken(r == ERROR_INSTALL_FAILURE), /* win9x */
5446        "Expected ERROR_SUCCESS, got %u\n", r);
5447     if (r == ERROR_SUCCESS)
5448     {
5449       ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5450       ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5451     }
5452     ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
5453     ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
5454     ok(delete_pf("msitest", FALSE), "File not installed\n");
5455
5456     create_pf("msitest", FALSE);
5457     create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
5458     create_pf("msitest\\gaius", TRUE);
5459
5460     r = MsiInstallProductA(msifile, "GAIUS=1");
5461     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5462     todo_wine
5463     {
5464         ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
5465         ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5466     }
5467     ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
5468     ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
5469     ok(delete_pf("msitest", FALSE), "File not installed\n");
5470
5471     DeleteFile("msitest\\augustus");
5472     RemoveDirectory("msitest");
5473     DeleteFile("maximus");
5474     DeleteFile("test1.cab");
5475     DeleteFile(msifile);
5476 }
5477
5478 static void test_duplicatefiles(void)
5479 {
5480     UINT r;
5481
5482     CreateDirectoryA("msitest", NULL);
5483     create_file("msitest\\maximus", 500);
5484     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
5485
5486     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5487
5488     /* fails if the destination folder is not a valid property */
5489
5490     r = MsiInstallProductA(msifile, NULL);
5491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5492     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
5493     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
5494     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
5495     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
5496     ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
5497     ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
5498     ok(delete_pf("msitest", FALSE), "File not installed\n");
5499
5500     DeleteFile("msitest\\maximus");
5501     RemoveDirectory("msitest");
5502     DeleteFile(msifile);
5503 }
5504
5505 static void test_writeregistryvalues(void)
5506 {
5507     UINT r;
5508     LONG res;
5509     HKEY hkey;
5510     DWORD type, size;
5511     CHAR path[MAX_PATH];
5512
5513     CreateDirectoryA("msitest", NULL);
5514     create_file("msitest\\augustus", 500);
5515
5516     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
5517
5518     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5519
5520     r = MsiInstallProductA(msifile, NULL);
5521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5522     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5523     ok(delete_pf("msitest", FALSE), "File installed\n");
5524
5525     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
5526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5527
5528     size = MAX_PATH;
5529     type = REG_MULTI_SZ;
5530     memset(path, 'a', MAX_PATH);
5531     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
5532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5533     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
5534     ok(size == 15, "Expected 15, got %d\n", size);
5535     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5536
5537     DeleteFile(msifile);
5538     DeleteFile("msitest\\augustus");
5539     RemoveDirectory("msitest");
5540
5541     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
5542     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
5543 }
5544
5545 static void test_sourcefolder(void)
5546 {
5547     UINT r;
5548
5549     CreateDirectoryA("msitest", NULL);
5550     create_file("augustus", 500);
5551
5552     create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
5553
5554     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5555
5556     r = MsiInstallProductA(msifile, NULL);
5557     ok(r == ERROR_INSTALL_FAILURE,
5558        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5559     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5560     todo_wine
5561     {
5562         ok(!delete_pf("msitest", FALSE), "File installed\n");
5563     }
5564
5565     RemoveDirectoryA("msitest");
5566
5567     r = MsiInstallProductA(msifile, NULL);
5568     ok(r == ERROR_INSTALL_FAILURE,
5569        "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5570     ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
5571     todo_wine
5572     {
5573         ok(!delete_pf("msitest", FALSE), "File installed\n");
5574     }
5575
5576     DeleteFile(msifile);
5577     DeleteFile("augustus");
5578 }
5579
5580 static void test_customaction51(void)
5581 {
5582     UINT r;
5583
5584     CreateDirectoryA("msitest", NULL);
5585     create_file("msitest\\augustus", 500);
5586
5587     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
5588
5589     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5590
5591     r = MsiInstallProductA(msifile, NULL);
5592     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5593     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
5594     ok(delete_pf("msitest", FALSE), "File installed\n");
5595
5596     DeleteFile(msifile);
5597     DeleteFile("msitest\\augustus");
5598     RemoveDirectory("msitest");
5599 }
5600
5601 static void test_installstate(void)
5602 {
5603     UINT r;
5604
5605     CreateDirectoryA("msitest", NULL);
5606     create_file("msitest\\alpha", 500);
5607     create_file("msitest\\beta", 500);
5608     create_file("msitest\\gamma", 500);
5609     create_file("msitest\\theta", 500);
5610     create_file("msitest\\delta", 500);
5611     create_file("msitest\\epsilon", 500);
5612     create_file("msitest\\zeta", 500);
5613     create_file("msitest\\iota", 500);
5614     create_file("msitest\\eta", 500);
5615     create_file("msitest\\kappa", 500);
5616     create_file("msitest\\lambda", 500);
5617     create_file("msitest\\mu", 500);
5618
5619     create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
5620
5621     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5622
5623     r = MsiInstallProductA(msifile, NULL);
5624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5625     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5626     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5627     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
5628     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5629     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5630     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5631     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
5632     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5633     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5634     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5635     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5636     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5637     ok(delete_pf("msitest", FALSE), "File not installed\n");
5638
5639     r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
5640     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5641     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5642     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5643     ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
5644     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5645     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5646     ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
5647     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
5648     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5649     ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
5650     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5651     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5652     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5653     ok(delete_pf("msitest", FALSE), "File not installed\n");
5654
5655     r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
5656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5657     ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
5658     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5659     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
5660     ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
5661     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5662     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5663     ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
5664     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5665     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5666     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5667     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5668     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5669     ok(delete_pf("msitest", FALSE), "File not installed\n");
5670
5671     r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
5672     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5673     ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
5674     ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
5675     ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
5676     ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
5677     ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
5678     ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
5679     ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
5680     ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
5681     ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
5682     ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
5683     ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
5684     ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
5685     ok(!delete_pf("msitest", FALSE), "File installed\n");
5686
5687     DeleteFile(msifile);
5688     DeleteFile("msitest\\alpha");
5689     DeleteFile("msitest\\beta");
5690     DeleteFile("msitest\\gamma");
5691     DeleteFile("msitest\\theta");
5692     DeleteFile("msitest\\delta");
5693     DeleteFile("msitest\\epsilon");
5694     DeleteFile("msitest\\zeta");
5695     DeleteFile("msitest\\iota");
5696     DeleteFile("msitest\\eta");
5697     DeleteFile("msitest\\kappa");
5698     DeleteFile("msitest\\lambda");
5699     DeleteFile("msitest\\mu");
5700     RemoveDirectory("msitest");
5701 }
5702
5703 struct sourcepathmap
5704 {
5705     BOOL sost; /* shortone\shorttwo */
5706     BOOL solt; /* shortone\longtwo */
5707     BOOL lost; /* longone\shorttwo */
5708     BOOL lolt; /* longone\longtwo */
5709     BOOL soste; /* shortone\shorttwo source exists */
5710     BOOL solte; /* shortone\longtwo source exists */
5711     BOOL loste; /* longone\shorttwo source exists */
5712     BOOL lolte; /* longone\longtwo source exists */
5713     UINT err;
5714     DWORD size;
5715 } spmap[256] =
5716 {
5717     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5718     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5719     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5720     {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5721     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5722     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5723     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5724     {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5725     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5726     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5727     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5728     {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5729     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5730     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5731     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5732     {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5733     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5734     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5735     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5736     {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5737     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5738     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5739     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5740     {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5741     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5742     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5743     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5744     {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5745     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5746     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5747     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5748     {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5749     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5750     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5751     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5752     {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5753     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5754     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5755     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5756     {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5757     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5758     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5759     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5760     {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5761     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5762     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5763     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5764     {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5765     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5766     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5767     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5768     {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5769     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5770     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5771     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5772     {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5773     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5774     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5775     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5776     {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5777     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5778     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5779     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5780     {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5781     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5782     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5783     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5784     {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5785     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5786     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5787     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5788     {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5789     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5790     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5791     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5792     {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5793     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5794     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5795     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5796     {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5797     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5798     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5799     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5800     {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5801     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5802     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5803     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5804     {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5805     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5806     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5807     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5808     {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5809     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5810     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5811     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5812     {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5813     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5814     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5815     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5816     {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5817     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5818     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5819     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5820     {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5821     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5822     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5823     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5824     {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5825     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5826     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5827     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5828     {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5829     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5830     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5831     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5832     {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5833     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5834     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5835     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5836     {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5837     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5838     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5839     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5840     {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5841     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5842     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5843     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5844     {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5845     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5846     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5847     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5848     {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5849     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5850     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5851     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5852     {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5853     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5854     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5855     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5856     {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5857     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5858     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5859     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5860     {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5861     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5862     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5863     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5864     {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5865     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5866     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5867     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5868     {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5869     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5870     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5871     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5872     {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5873     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5874     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5875     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5876     {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5877     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5878     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5879     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5880     {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5881     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5882     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5883     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5884     {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5885     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5886     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5887     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5888     {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5889     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5890     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5891     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5892     {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5893     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5894     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5895     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5896     {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5897     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5898     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5899     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5900     {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5901     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5902     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5903     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5904     {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5905     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5906     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5907     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5908     {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5909     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5910     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5911     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5912     {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5913     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5914     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5915     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5916     {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5917     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5918     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5919     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5920     {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5921     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5922     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5923     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5924     {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5925     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5926     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5927     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5928     {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5929     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5930     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5931     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5932     {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5933     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5934     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5935     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5936     {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5937     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5938     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5939     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5940     {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5941     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5942     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5943     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5944     {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5945     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5946     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5947     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5948     {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5949     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200},
5950     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5951     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200},
5952     {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5953     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200},
5954     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5955     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200},
5956     {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5957     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5958     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5959     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5960     {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5961     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5962     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5963     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5964     {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5965     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5966     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5967     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5968     {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5969     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0},
5970     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0},
5971     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0},
5972     {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0},
5973 };
5974
5975 static DWORD get_pf_file_size(LPCSTR file)
5976 {
5977     CHAR path[MAX_PATH];
5978     HANDLE hfile;
5979     DWORD size;
5980
5981     lstrcpyA(path, PROG_FILES_DIR);
5982     lstrcatA(path, "\\");
5983     lstrcatA(path, file);
5984
5985     hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
5986     if (hfile == INVALID_HANDLE_VALUE)
5987         return 0;
5988
5989     size = GetFileSize(hfile, NULL);
5990     CloseHandle(hfile);
5991     return size;
5992 }
5993
5994 static void test_sourcepath(void)
5995 {
5996     UINT r, i;
5997
5998     if (!winetest_interactive)
5999     {
6000         skip("Run in interactive mode to run source path tests.\n");
6001         return;
6002     }
6003
6004     create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table));
6005
6006     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6007
6008     for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++)
6009     {
6010         if (spmap[i].sost)
6011         {
6012             CreateDirectoryA("shortone", NULL);
6013             CreateDirectoryA("shortone\\shorttwo", NULL);
6014         }
6015
6016         if (spmap[i].solt)
6017         {
6018             CreateDirectoryA("shortone", NULL);
6019             CreateDirectoryA("shortone\\longtwo", NULL);
6020         }
6021
6022         if (spmap[i].lost)
6023         {
6024             CreateDirectoryA("longone", NULL);
6025             CreateDirectoryA("longone\\shorttwo", NULL);
6026         }
6027
6028         if (spmap[i].lolt)
6029         {
6030             CreateDirectoryA("longone", NULL);
6031             CreateDirectoryA("longone\\longtwo", NULL);
6032         }
6033
6034         if (spmap[i].soste)
6035             create_file("shortone\\shorttwo\\augustus", 50);
6036         if (spmap[i].solte)
6037             create_file("shortone\\longtwo\\augustus", 100);
6038         if (spmap[i].loste)
6039             create_file("longone\\shorttwo\\augustus", 150);
6040         if (spmap[i].lolte)
6041             create_file("longone\\longtwo\\augustus", 200);
6042
6043         r = MsiInstallProductA(msifile, NULL);
6044         ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r);
6045         ok(get_pf_file_size("msitest\\augustus") == spmap[i].size,
6046            "%d: Expected %d, got %d\n", i, spmap[i].size,
6047            get_pf_file_size("msitest\\augustus"));
6048
6049         if (r == ERROR_SUCCESS)
6050         {
6051             ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i);
6052             ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i);
6053         }
6054         else
6055         {
6056             ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i);
6057             todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i);
6058         }
6059
6060         DeleteFileA("shortone\\shorttwo\\augustus");
6061         DeleteFileA("shortone\\longtwo\\augustus");
6062         DeleteFileA("longone\\shorttwo\\augustus");
6063         DeleteFileA("longone\\longtwo\\augustus");
6064         RemoveDirectoryA("shortone\\shorttwo");
6065         RemoveDirectoryA("shortone\\longtwo");
6066         RemoveDirectoryA("longone\\shorttwo");
6067         RemoveDirectoryA("longone\\longtwo");
6068         RemoveDirectoryA("shortone");
6069         RemoveDirectoryA("longone");
6070     }
6071
6072     DeleteFileA(msifile);
6073 }
6074
6075 static void test_MsiConfigureProductEx(void)
6076 {
6077     UINT r;
6078     LONG res;
6079     DWORD type, size;
6080     HKEY props, source;
6081     CHAR keypath[MAX_PATH * 2];
6082     CHAR localpack[MAX_PATH];
6083
6084     if (on_win9x)
6085     {
6086         win_skip("Different registry keys on Win9x and WinMe\n");
6087         return;
6088     }
6089
6090     CreateDirectoryA("msitest", NULL);
6091     create_file("msitest\\hydrogen", 500);
6092     create_file("msitest\\helium", 500);
6093     create_file("msitest\\lithium", 500);
6094
6095     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6096
6097     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6098
6099     /* NULL szProduct */
6100     r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
6101                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6102     ok(r == ERROR_INVALID_PARAMETER,
6103        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6104
6105     /* empty szProduct */
6106     r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
6107                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6108     ok(r == ERROR_INVALID_PARAMETER,
6109        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6110
6111     /* garbage szProduct */
6112     r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
6113                                INSTALLSTATE_DEFAULT, "PROPVAR=42");
6114     ok(r == ERROR_INVALID_PARAMETER,
6115        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6116
6117     /* guid without brackets */
6118     r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6119                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6120                                "PROPVAR=42");
6121     ok(r == ERROR_INVALID_PARAMETER,
6122        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6123
6124     /* guid with brackets */
6125     r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6126                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6127                                "PROPVAR=42");
6128     ok(r == ERROR_UNKNOWN_PRODUCT,
6129        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6130
6131     /* same length as guid, but random */
6132     r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
6133                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6134                                "PROPVAR=42");
6135     ok(r == ERROR_UNKNOWN_PRODUCT,
6136        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6137
6138     /* product not installed yet */
6139     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6140                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6141                                "PROPVAR=42");
6142     ok(r == ERROR_UNKNOWN_PRODUCT,
6143        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6144
6145     /* install the product, per-user unmanaged */
6146     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
6147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6148     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6149     ok(pf_exists("msitest\\helium"), "File not installed\n");
6150     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6151     ok(pf_exists("msitest"), "File not installed\n");
6152
6153     /* product is installed per-user managed, remove it */
6154     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6155                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6156                                "PROPVAR=42");
6157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6158     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6159     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6160     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6161     todo_wine
6162     {
6163         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6164     }
6165
6166     /* product has been removed */
6167     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6168                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6169                                "PROPVAR=42");
6170     ok(r == ERROR_UNKNOWN_PRODUCT,
6171        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
6172
6173     /* install the product, machine */
6174     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6175     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6176     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6177     ok(pf_exists("msitest\\helium"), "File not installed\n");
6178     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6179     ok(pf_exists("msitest"), "File not installed\n");
6180
6181     /* product is installed machine, remove it */
6182     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6183                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6184                                "PROPVAR=42");
6185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6186     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6187     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6188     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6189     todo_wine
6190     {
6191         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6192     }
6193
6194     /* product has been removed */
6195     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6196                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
6197                                "PROPVAR=42");
6198     ok(r == ERROR_UNKNOWN_PRODUCT,
6199        "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
6200
6201     /* install the product, machine */
6202     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6204     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6205     ok(pf_exists("msitest\\helium"), "File not installed\n");
6206     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6207     ok(pf_exists("msitest"), "File not installed\n");
6208
6209     DeleteFileA(msifile);
6210
6211     /* local msifile is removed */
6212     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6213                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6214                                "PROPVAR=42");
6215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6216     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6217     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6218     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6219     todo_wine
6220     {
6221         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6222     }
6223
6224     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6225
6226     /* install the product, machine */
6227     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6229     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6230     ok(pf_exists("msitest\\helium"), "File not installed\n");
6231     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6232     ok(pf_exists("msitest"), "File not installed\n");
6233
6234     DeleteFileA(msifile);
6235
6236     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
6237     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
6238     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
6239
6240     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
6241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6242
6243     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
6244                          (const BYTE *)"C:\\idontexist.msi", 18);
6245     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6246
6247     /* LocalPackage is used to find the cached msi package */
6248     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6249                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6250                                "PROPVAR=42");
6251     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
6252        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
6253     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6254     ok(pf_exists("msitest\\helium"), "File not installed\n");
6255     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6256     ok(pf_exists("msitest"), "File not installed\n");
6257
6258     RegCloseKey(props);
6259     create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
6260
6261     /* LastUsedSource (local msi package) can be used as a last resort */
6262     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6263                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6264                                "PROPVAR=42");
6265     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6266     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6267     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6268     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6269     todo_wine
6270     {
6271         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6272     }
6273
6274     /* install the product, machine */
6275     r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
6276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6277     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6278     ok(pf_exists("msitest\\helium"), "File not installed\n");
6279     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6280     ok(pf_exists("msitest"), "File not installed\n");
6281
6282     lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
6283     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
6284     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties");
6285
6286     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
6287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6288
6289     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
6290                          (const BYTE *)"C:\\idontexist.msi", 18);
6291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6292
6293     lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
6294     lstrcatA(keypath, "84A88FD7F6998CE40A22FB59F6B9C2BB\\SourceList");
6295
6296     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &source);
6297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6298
6299     type = REG_SZ;
6300     size = MAX_PATH;
6301     res = RegQueryValueExA(source, "PackageName", NULL, &type,
6302                            (LPBYTE)localpack, &size);
6303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6304
6305     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
6306                          (const BYTE *)"idontexist.msi", 15);
6307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6308
6309     /* SourceList is altered */
6310     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6311                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6312                                "PROPVAR=42");
6313     ok(r == ERROR_INSTALL_SOURCE_ABSENT,
6314        "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
6315     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6316     ok(pf_exists("msitest\\helium"), "File not installed\n");
6317     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6318     ok(pf_exists("msitest"), "File not installed\n");
6319
6320     /* restore the SourceList */
6321     res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
6322                          (const BYTE *)localpack, lstrlenA(localpack) + 1);
6323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6324
6325     /* finally remove the product */
6326     r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
6327                                INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
6328                                "PROPVAR=42");
6329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6330     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6331     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6332     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6333     todo_wine
6334     {
6335         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6336     }
6337
6338     DeleteFileA(msifile);
6339     RegCloseKey(source);
6340     RegCloseKey(props);
6341     DeleteFileA("msitest\\hydrogen");
6342     DeleteFileA("msitest\\helium");
6343     DeleteFileA("msitest\\lithium");
6344     RemoveDirectoryA("msitest");
6345 }
6346
6347 static void test_missingcomponent(void)
6348 {
6349     UINT r;
6350
6351     CreateDirectoryA("msitest", NULL);
6352     create_file("msitest\\hydrogen", 500);
6353     create_file("msitest\\helium", 500);
6354     create_file("msitest\\lithium", 500);
6355     create_file("beryllium", 500);
6356
6357     create_database(msifile, mcomp_tables, sizeof(mcomp_tables) / sizeof(msi_table));
6358
6359     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6360
6361     r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
6362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6363     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
6364     ok(pf_exists("msitest\\helium"), "File not installed\n");
6365     ok(pf_exists("msitest\\lithium"), "File not installed\n");
6366     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
6367     ok(pf_exists("msitest"), "File not installed\n");
6368
6369     r = MsiInstallProductA(msifile, "REMOVE=ALL INSTALLLEVEL=10 PROPVAR=42");
6370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6371     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
6372     ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
6373     ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
6374     ok(!pf_exists("msitest\\beryllium"), "File installed\n");
6375     todo_wine
6376     {
6377         ok(!delete_pf("msitest", FALSE), "File not removed\n");
6378     }
6379
6380     DeleteFileA(msifile);
6381     DeleteFileA("msitest\\hydrogen");
6382     DeleteFileA("msitest\\helium");
6383     DeleteFileA("msitest\\lithium");
6384     DeleteFileA("beryllium");
6385     RemoveDirectoryA("msitest");
6386 }
6387
6388 static void test_sourcedirprop(void)
6389 {
6390     UINT r;
6391     CHAR props[MAX_PATH];
6392
6393     CreateDirectoryA("msitest", NULL);
6394     create_file("msitest\\augustus", 500);
6395
6396     create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
6397
6398     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6399
6400     r = MsiInstallProductA(msifile, NULL);
6401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6402     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6403     ok(delete_pf("msitest", FALSE), "File installed\n");
6404
6405     DeleteFile("msitest\\augustus");
6406     RemoveDirectory("msitest");
6407
6408     CreateDirectoryA("altsource", NULL);
6409     CreateDirectoryA("altsource\\msitest", NULL);
6410     create_file("altsource\\msitest\\augustus", 500);
6411
6412     sprintf(props, "SRCDIR=%s\\altsource\\", CURR_DIR);
6413
6414     r = MsiInstallProductA(msifile, props);
6415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6416     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
6417     ok(delete_pf("msitest", FALSE), "File installed\n");
6418
6419     DeleteFile(msifile);
6420     DeleteFile("altsource\\msitest\\augustus");
6421     RemoveDirectory("altsource\\msitest");
6422     RemoveDirectory("altsource");
6423 }
6424
6425 static void test_adminimage(void)
6426 {
6427     UINT r;
6428
6429     CreateDirectoryA("msitest", NULL);
6430     CreateDirectoryA("msitest\\first", NULL);
6431     CreateDirectoryA("msitest\\second", NULL);
6432     CreateDirectoryA("msitest\\cabout", NULL);
6433     CreateDirectoryA("msitest\\cabout\\new", NULL);
6434     create_file("msitest\\one.txt", 100);
6435     create_file("msitest\\first\\two.txt", 100);
6436     create_file("msitest\\second\\three.txt", 100);
6437     create_file("msitest\\cabout\\four.txt", 100);
6438     create_file("msitest\\cabout\\new\\five.txt", 100);
6439     create_file("msitest\\filename", 100);
6440     create_file("msitest\\service.exe", 100);
6441
6442     create_database_wordcount(msifile, ai_tables,
6443                               sizeof(ai_tables) / sizeof(msi_table),
6444                               msidbSumInfoSourceTypeAdminImage);
6445
6446     r = MsiInstallProductA(msifile, NULL);
6447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6448
6449     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6450     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6451     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6452     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6453     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6454     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6455     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6456     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6457     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
6458     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6459     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6460     ok(delete_pf("msitest", FALSE), "File not installed\n");
6461
6462     DeleteFileA("msitest.msi");
6463     DeleteFileA("msitest\\cabout\\new\\five.txt");
6464     DeleteFileA("msitest\\cabout\\four.txt");
6465     DeleteFileA("msitest\\second\\three.txt");
6466     DeleteFileA("msitest\\first\\two.txt");
6467     DeleteFileA("msitest\\one.txt");
6468     DeleteFileA("msitest\\service.exe");
6469     DeleteFileA("msitest\\filename");
6470     RemoveDirectoryA("msitest\\cabout\\new");
6471     RemoveDirectoryA("msitest\\cabout");
6472     RemoveDirectoryA("msitest\\second");
6473     RemoveDirectoryA("msitest\\first");
6474     RemoveDirectoryA("msitest");
6475 }
6476
6477 static void test_propcase(void)
6478 {
6479     UINT r;
6480
6481     CreateDirectoryA("msitest", NULL);
6482     create_file("msitest\\augustus", 500);
6483
6484     create_database(msifile, pc_tables, sizeof(pc_tables) / sizeof(msi_table));
6485
6486     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6487
6488     r = MsiInstallProductA(msifile, "MyProp=42");
6489     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6490     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
6491     ok(delete_pf("msitest", FALSE), "File not installed\n");
6492
6493     DeleteFile(msifile);
6494     DeleteFile("msitest\\augustus");
6495     RemoveDirectory("msitest");
6496 }
6497
6498 static void test_int_widths( void )
6499 {
6500     static const char int0[] = "int0\ni0\nint0\tint0\n1";
6501     static const char int1[] = "int1\ni1\nint1\tint1\n1";
6502     static const char int2[] = "int2\ni2\nint2\tint2\n1";
6503     static const char int3[] = "int3\ni3\nint3\tint3\n1";
6504     static const char int4[] = "int4\ni4\nint4\tint4\n1";
6505     static const char int5[] = "int5\ni5\nint5\tint5\n1";
6506     static const char int8[] = "int8\ni8\nint8\tint8\n1";
6507
6508     static const struct
6509     {
6510         const char  *data;
6511         unsigned int size;
6512         UINT         ret;
6513     }
6514     tests[] =
6515     {
6516         { int0, sizeof(int0) - 1, ERROR_SUCCESS },
6517         { int1, sizeof(int1) - 1, ERROR_SUCCESS },
6518         { int2, sizeof(int2) - 1, ERROR_SUCCESS },
6519         { int3, sizeof(int3) - 1, ERROR_FUNCTION_FAILED },
6520         { int4, sizeof(int4) - 1, ERROR_SUCCESS },
6521         { int5, sizeof(int5) - 1, ERROR_FUNCTION_FAILED },
6522         { int8, sizeof(int8) - 1, ERROR_FUNCTION_FAILED }
6523     };
6524
6525     char tmpdir[MAX_PATH], msitable[MAX_PATH], msidb[MAX_PATH];
6526     MSIHANDLE db;
6527     UINT r, i;
6528
6529     GetTempPathA(MAX_PATH, tmpdir);
6530     CreateDirectoryA(tmpdir, NULL);
6531
6532     strcpy(msitable, tmpdir);
6533     strcat(msitable, "\\msitable.idt");
6534
6535     strcpy(msidb, tmpdir);
6536     strcat(msidb, "\\msitest.msi");
6537
6538     r = MsiOpenDatabaseA(msidb, MSIDBOPEN_CREATE, &db);
6539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6540
6541     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
6542     {
6543         write_file(msitable, tests[i].data, tests[i].size);
6544
6545         r = MsiDatabaseImportA(db, tmpdir, "msitable.idt");
6546         ok(r == tests[i].ret, " %u expected %u, got %u\n", i, tests[i].ret, r);
6547
6548         r = MsiDatabaseCommit(db);
6549         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6550         DeleteFileA(msitable);
6551     }
6552
6553     MsiCloseHandle(db);
6554     DeleteFileA(msidb);
6555     RemoveDirectoryA(tmpdir);
6556 }
6557
6558 static void test_shortcut(void)
6559 {
6560     UINT r;
6561     HRESULT hr;
6562
6563     create_test_files();
6564     create_database(msifile, sc_tables, sizeof(sc_tables) / sizeof(msi_table));
6565
6566     r = MsiInstallProductA(msifile, NULL);
6567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6568
6569     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
6570     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
6571
6572     r = MsiInstallProductA(msifile, NULL);
6573     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6574
6575     CoUninitialize();
6576
6577     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
6578     ok(SUCCEEDED(hr), "CoInitialize failed 0x%08x\n", hr);
6579
6580     r = MsiInstallProductA(msifile, NULL);
6581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6582
6583     CoUninitialize();
6584
6585     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
6586     delete_pf("msitest\\cabout\\new", FALSE);
6587     delete_pf("msitest\\cabout\\four.txt", TRUE);
6588     delete_pf("msitest\\cabout", FALSE);
6589     delete_pf("msitest\\changed\\three.txt", TRUE);
6590     delete_pf("msitest\\changed", FALSE);
6591     delete_pf("msitest\\first\\two.txt", TRUE);
6592     delete_pf("msitest\\first", FALSE);
6593     delete_pf("msitest\\filename", TRUE);
6594     delete_pf("msitest\\one.txt", TRUE);
6595     delete_pf("msitest\\service.exe", TRUE);
6596     delete_pf("msitest\\Shortcut.lnk", TRUE);
6597     delete_pf("msitest", FALSE);
6598     delete_test_files();
6599 }
6600
6601 static void test_envvar(void)
6602 {
6603     UINT r;
6604     HKEY env;
6605     LONG res;
6606     DWORD type, size;
6607     char buffer[16];
6608
6609     if (on_win9x)
6610     {
6611         win_skip("Environment variables are handled differently on Win9x and WinMe\n");
6612         return;
6613     }
6614
6615     create_test_files();
6616     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
6617
6618     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
6619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6620
6621     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
6622     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6623
6624     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
6625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6626
6627     r = MsiInstallProductA(msifile, NULL);
6628     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6629
6630     type = REG_NONE;
6631     size = sizeof(buffer);
6632     buffer[0] = 0;
6633     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
6634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6635     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
6636     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
6637
6638     res = RegDeleteValueA(env, "MSITESTVAR1");
6639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6640
6641     type = REG_NONE;
6642     size = sizeof(buffer);
6643     buffer[0] = 0;
6644     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
6645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6646     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
6647     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
6648
6649     res = RegDeleteValueA(env, "MSITESTVAR2");
6650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6651
6652     res = RegDeleteValueA(env, "MSITESTVAR3");
6653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6654
6655     res = RegDeleteValueA(env, "MSITESTVAR4");
6656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6657
6658     res = RegDeleteValueA(env, "MSITESTVAR5");
6659     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6660
6661     res = RegDeleteValueA(env, "MSITESTVAR6");
6662     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6663
6664     res = RegDeleteValueA(env, "MSITESTVAR7");
6665     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6666
6667     res = RegDeleteValueA(env, "MSITESTVAR8");
6668     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6669
6670     res = RegDeleteValueA(env, "MSITESTVAR9");
6671     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6672
6673     res = RegDeleteValueA(env, "MSITESTVAR10");
6674     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6675
6676     RegCloseKey(env);
6677
6678     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
6679     delete_pf("msitest\\cabout\\new", FALSE);
6680     delete_pf("msitest\\cabout\\four.txt", TRUE);
6681     delete_pf("msitest\\cabout", FALSE);
6682     delete_pf("msitest\\changed\\three.txt", TRUE);
6683     delete_pf("msitest\\changed", FALSE);
6684     delete_pf("msitest\\first\\two.txt", TRUE);
6685     delete_pf("msitest\\first", FALSE);
6686     delete_pf("msitest\\filename", TRUE);
6687     delete_pf("msitest\\one.txt", TRUE);
6688     delete_pf("msitest\\service.exe", TRUE);
6689     delete_pf("msitest", FALSE);
6690     delete_test_files();
6691 }
6692
6693 static void test_preselected(void)
6694 {
6695     UINT r;
6696
6697     create_test_files();
6698     create_database(msifile, ps_tables, sizeof(ps_tables) / sizeof(msi_table));
6699
6700     r = MsiInstallProductA(msifile, "ADDLOCAL=One");
6701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6702
6703     ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
6704     ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
6705     ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
6706     ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
6707     ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
6708     ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
6709     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
6710     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
6711     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
6712     todo_wine ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
6713     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
6714     todo_wine ok(delete_pf("msitest", FALSE), "File not installed\n");
6715
6716     r = MsiInstallProductA(msifile, NULL);
6717     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6718
6719     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6720     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6721     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6722     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6723     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6724     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6725     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6726     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6727     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6728     ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
6729     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6730     ok(delete_pf("msitest", FALSE), "File not installed\n");
6731     delete_test_files();
6732 }
6733
6734 static void test_installed_prop(void)
6735 {
6736     static char prodcode[] = "{7df88a48-996f-4ec8-a022-bf956f9b2cbb}";
6737     UINT r;
6738
6739     create_test_files();
6740     create_database(msifile, ip_tables, sizeof(ip_tables) / sizeof(msi_table));
6741
6742     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6743
6744     r = MsiInstallProductA(msifile, "FULL=1");
6745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6746
6747     r = MsiInstallProductA(msifile, "FULL=1");
6748     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6749
6750     r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1");
6751     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
6752
6753     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6754     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6755     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6756     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6757     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6758     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6759     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6760     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6761     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6762     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
6763     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6764     ok(delete_pf("msitest", FALSE), "File not installed\n");
6765
6766     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6767     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6768
6769     delete_test_files();
6770 }
6771
6772 static void test_allusers_prop(void)
6773 {
6774     UINT r;
6775
6776     create_test_files();
6777     create_database(msifile, aup_tables, sizeof(aup_tables) / sizeof(msi_table));
6778
6779     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6780
6781     r = MsiInstallProductA(msifile, "FULL=1");
6782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6783
6784     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
6785     ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
6786     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
6787     ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
6788     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
6789     ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
6790     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
6791     ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
6792     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
6793     ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n");
6794     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
6795     ok(delete_pf("msitest", FALSE), "File not installed\n");
6796
6797     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6798     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6799
6800     delete_test_files();
6801 }
6802
6803 static char session_manager[] = "System\\CurrentControlSet\\Control\\Session Manager";
6804 static char rename_ops[]      = "PendingFileRenameOperations";
6805
6806 static void process_pending_renames(HKEY hkey)
6807 {
6808     char *buf, *src, *dst;
6809     DWORD size;
6810     LONG ret;
6811
6812     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size);
6813     buf = HeapAlloc(GetProcessHeap(), 0, size);
6814     buf[0] = 0;
6815
6816     ret = RegQueryValueExA(hkey, rename_ops, NULL, NULL, (LPBYTE)buf, &size);
6817     ok(!ret, "RegQueryValueExA failed %d (%u)\n", ret, GetLastError());
6818     ok(strstr(buf, "msitest\\maximus") != NULL, "Unexpected value \"%s\"\n", buf);
6819
6820     for (src = buf; *src; src = dst + strlen(dst) + 1)
6821     {
6822         DWORD flags = MOVEFILE_COPY_ALLOWED;
6823
6824         dst = src + strlen(src) + 1;
6825         if (*dst == '!')
6826         {
6827             flags |= MOVEFILE_REPLACE_EXISTING;
6828             dst++;
6829         }
6830         if (src[0] == '\\' && src[1] == '?' && src[2] == '?' && src[3] == '\\') src += 4;
6831         if (*dst)
6832         {
6833             if (dst[0] == '\\' && dst[1] == '?' && dst[2] == '?' && dst[3] == '\\') dst += 4;
6834             ok(MoveFileExA(src, dst, flags), "Failed to move file %s -> %s (%u)\n", src, dst, GetLastError());
6835         }
6836         else
6837             ok(DeleteFileA(src), "Failed to delete file %s (%u)\n", src, GetLastError());
6838     }
6839     HeapFree(GetProcessHeap(), 0, buf);
6840     RegDeleteValueA(hkey, rename_ops);
6841 }
6842
6843 static BOOL file_matches_data(LPCSTR file, LPCSTR data)
6844 {
6845     DWORD len, data_len = strlen(data);
6846     HANDLE handle;
6847     char buf[128];
6848
6849     handle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
6850     ok(handle != INVALID_HANDLE_VALUE, "failed to open %s (%u)\n", file, GetLastError());
6851
6852     if (ReadFile(handle, buf, sizeof(buf), &len, NULL) && len >= data_len)
6853     {
6854         CloseHandle(handle);
6855         return !memcmp(buf, data, data_len);
6856     }
6857     CloseHandle(handle);
6858     return FALSE;
6859 }
6860
6861 static void test_file_in_use(void)
6862 {
6863     UINT r;
6864     DWORD size;
6865     HANDLE file;
6866     HKEY hkey;
6867     char path[MAX_PATH];
6868
6869     if (on_win9x)
6870     {
6871         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
6872         return;
6873     }
6874
6875     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
6876     if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size))
6877     {
6878         skip("Pending file rename operations, skipping test\n");
6879         return;
6880     }
6881
6882     CreateDirectoryA("msitest", NULL);
6883     create_file("msitest\\maximus", 500);
6884     create_database(msifile, fiu_tables, sizeof(fiu_tables) / sizeof(msi_table));
6885
6886     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6887
6888     lstrcpy(path, PROG_FILES_DIR);
6889     lstrcat(path, "\\msitest");
6890     CreateDirectoryA(path, NULL);
6891
6892     lstrcat(path, "\\maximus");
6893     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
6894
6895     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
6896     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
6897     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
6898     CloseHandle(file);
6899     ok(!file_matches_data(path, "msitest\\maximus"), "Expected file not to match\n");
6900
6901     process_pending_renames(hkey);
6902     RegCloseKey(hkey);
6903
6904     ok(file_matches_data(path, "msitest\\maximus"), "Expected file to match\n");
6905     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
6906     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
6907
6908     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6910
6911     delete_test_files();
6912 }
6913
6914 static void test_file_in_use_cab(void)
6915 {
6916     UINT r;
6917     DWORD size;
6918     HANDLE file;
6919     HKEY hkey;
6920     char path[MAX_PATH];
6921
6922     if (on_win9x)
6923     {
6924         win_skip("Pending file renaming is implemented differently on Win9x and WinMe\n");
6925         return;
6926     }
6927
6928     RegOpenKeyExA(HKEY_LOCAL_MACHINE, session_manager, 0, KEY_ALL_ACCESS, &hkey);
6929     if (!RegQueryValueExA(hkey, rename_ops, NULL, NULL, NULL, &size))
6930     {
6931         skip("Pending file rename operations, skipping test\n");
6932         return;
6933     }
6934
6935     CreateDirectoryA("msitest", NULL);
6936     create_file("maximus", 500);
6937     create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
6938     DeleteFile("maximus");
6939
6940     create_database(msifile, fiuc_tables, sizeof(fiuc_tables) / sizeof(msi_table));
6941
6942     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6943
6944     lstrcpy(path, PROG_FILES_DIR);
6945     lstrcat(path, "\\msitest");
6946     CreateDirectoryA(path, NULL);
6947
6948     lstrcat(path, "\\maximus");
6949     file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
6950
6951     r = MsiInstallProductA(msifile, "REBOOT=ReallySuppress FULL=1");
6952     ok(r == ERROR_SUCCESS_REBOOT_REQUIRED, "Expected ERROR_SUCCESS_REBOOT_REQUIRED got %u\n", r);
6953     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
6954     CloseHandle(file);
6955     ok(!file_matches_data(path, "maximus"), "Expected file not to match\n");
6956
6957     process_pending_renames(hkey);
6958     RegCloseKey(hkey);
6959
6960     ok(file_matches_data(path, "maximus"), "Expected file to match\n");
6961     ok(delete_pf("msitest\\maximus", TRUE), "File not present\n");
6962     ok(delete_pf("msitest", FALSE), "Directory not present or not empty\n");
6963
6964     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6965     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6966
6967     delete_cab_files();
6968     delete_test_files();
6969 }
6970
6971 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
6972 {
6973     return IDOK;
6974 }
6975
6976 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
6977 {
6978     return IDOK;
6979 }
6980
6981 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
6982 {
6983     return IDOK;
6984 }
6985
6986 static void test_MsiSetExternalUI(void)
6987 {
6988     INSTALLUI_HANDLERA ret_a;
6989     INSTALLUI_HANDLERW ret_w;
6990     INSTALLUI_HANDLER_RECORD prev;
6991     UINT error;
6992
6993     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
6994     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
6995
6996     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
6997     ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
6998
6999     /* Not present before Installer 3.1 */
7000     if (!pMsiSetExternalUIRecord) {
7001         win_skip("MsiSetExternalUIRecord is not available\n");
7002         return;
7003     }
7004
7005     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
7006     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7007     ok(prev == NULL, "expected NULL, got %p\n", prev);
7008
7009     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7010     error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
7011     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7012     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
7013
7014     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
7015     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7016
7017     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
7018     ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
7019
7020     ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
7021     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7022
7023     ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
7024     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7025
7026     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7027     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
7028     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7029     ok(prev == NULL, "expected NULL, got %p\n", prev);
7030
7031     ret_a = MsiSetExternalUIA(NULL, 0, NULL);
7032     ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
7033
7034     ret_w = MsiSetExternalUIW(NULL, 0, NULL);
7035     ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
7036
7037     prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
7038     error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
7039     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7040     ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
7041
7042     error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
7043     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7044
7045     error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
7046     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
7047 }
7048
7049 START_TEST(install)
7050 {
7051     DWORD len;
7052     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
7053     STATEMGRSTATUS status;
7054     BOOL ret = FALSE;
7055
7056     init_functionpointers();
7057
7058     on_win9x = check_win9x();
7059
7060     GetCurrentDirectoryA(MAX_PATH, prev_path);
7061     GetTempPath(MAX_PATH, temp_path);
7062     SetCurrentDirectoryA(temp_path);
7063
7064     lstrcpyA(CURR_DIR, temp_path);
7065     len = lstrlenA(CURR_DIR);
7066
7067     if(len && (CURR_DIR[len - 1] == '\\'))
7068         CURR_DIR[len - 1] = 0;
7069
7070     get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
7071
7072     /* Create a restore point ourselves so we circumvent the multitude of restore points
7073      * that would have been created by all the installation and removal tests.
7074      */
7075     if (pSRSetRestorePointA)
7076     {
7077         memset(&status, 0, sizeof(status));
7078         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
7079     }
7080
7081     /* Create only one log file and don't append. We have to pass something
7082      * for the log mode for this to work. The logfile needs to have an absolute
7083      * path otherwise we still end up with some extra logfiles as some tests
7084      * change the current directory.
7085      */
7086     lstrcpyA(log_file, temp_path);
7087     lstrcatA(log_file, "\\msitest.log");
7088     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
7089
7090     test_MsiInstallProduct();
7091     test_MsiSetComponentState();
7092     test_packagecoltypes();
7093     test_continuouscabs();
7094     test_caborder();
7095     test_mixedmedia();
7096     test_samesequence();
7097     test_uiLevelFlags();
7098     test_readonlyfile();
7099     test_readonlyfile_cab();
7100     test_setdirproperty();
7101     test_cabisextracted();
7102     test_concurrentinstall();
7103     test_setpropertyfolder();
7104     test_publish_registerproduct();
7105     test_publish_publishproduct();
7106     test_publish_publishfeatures();
7107     test_publish_registeruser();
7108     test_publish_processcomponents();
7109     test_publish();
7110     test_publishsourcelist();
7111     test_transformprop();
7112     test_currentworkingdir();
7113     test_admin();
7114     test_adminprops();
7115     test_removefiles();
7116     test_movefiles();
7117     test_missingcab();
7118     test_duplicatefiles();
7119     test_writeregistryvalues();
7120     test_sourcefolder();
7121     test_customaction51();
7122     test_installstate();
7123     test_sourcepath();
7124     test_MsiConfigureProductEx();
7125     test_missingcomponent();
7126     test_sourcedirprop();
7127     test_adminimage();
7128     test_propcase();
7129     test_int_widths();
7130     test_shortcut();
7131     test_envvar();
7132     test_lastusedsource();
7133     test_preselected();
7134     test_installed_prop();
7135     test_file_in_use();
7136     test_file_in_use_cab();
7137     test_MsiSetExternalUI();
7138     test_allusers_prop();
7139
7140     DeleteFileA(log_file);
7141
7142     if (pSRSetRestorePointA && ret)
7143     {
7144         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
7145         if (ret)
7146             remove_restore_point(status.llSequenceNumber);
7147     }
7148     FreeLibrary(hsrclient);
7149
7150     SetCurrentDirectoryA(prev_path);
7151 }