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