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