Autosyncing with Wine HEAD
[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
33 #include "wine/test.h"
34
35 static UINT (WINAPI *pMsiQueryComponentStateA)
36 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
37 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
38 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
39 static UINT (WINAPI *pMsiSourceListGetInfoA)
40 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
41
42 static const char *msifile = "msitest.msi";
43 static const char *msifile2 = "winetest2.msi";
44 static const char *mstfile = "winetest.mst";
45 static CHAR CURR_DIR[MAX_PATH];
46 static CHAR PROG_FILES_DIR[MAX_PATH];
47 static CHAR COMMON_FILES_DIR[MAX_PATH];
48
49 /* msi database data */
50
51 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
52 "s72\tS38\ts72\ti2\tS255\tS72\n"
53 "Component\tComponent\n"
54 "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
55 "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
56 "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\t\tone.txt\n"
57 "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
58 "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
59 "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
60 "component\t\tMSITESTDIR\t0\t1\tfile\n"
61 "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
62
63 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
64 "s72\tS72\tl255\n"
65 "Directory\tDirectory\n"
66 "CABOUTDIR\tMSITESTDIR\tcabout\n"
67 "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
68 "FIRSTDIR\tMSITESTDIR\tfirst\n"
69 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
70 "NEWDIR\tCABOUTDIR\tnew\n"
71 "ProgramFilesFolder\tTARGETDIR\t.\n"
72 "TARGETDIR\t\tSourceDir";
73
74 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
75 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
76 "Feature\tFeature\n"
77 "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
78 "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
79 "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
80 "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
81 "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
82 "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
83 "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
84
85 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
86 "s38\ts72\n"
87 "FeatureComponents\tFeature_\tComponent_\n"
88 "Five\tFive\n"
89 "Four\tFour\n"
90 "One\tOne\n"
91 "Three\tThree\n"
92 "Two\tTwo\n"
93 "feature\tcomponent\n"
94 "service_feature\tservice_comp\n";
95
96 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
97 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
98 "File\tFile\n"
99 "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
100 "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
101 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
102 "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
103 "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
104 "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
105 "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
106
107 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
108 "s72\tS255\tI2\n"
109 "InstallExecuteSequence\tAction\n"
110 "AllocateRegistrySpace\tNOT Installed\t1550\n"
111 "CostFinalize\t\t1000\n"
112 "CostInitialize\t\t800\n"
113 "FileCost\t\t900\n"
114 "ResolveSource\t\t950\n"
115 "MoveFiles\t\t1700\n"
116 "InstallFiles\t\t4000\n"
117 "DuplicateFiles\t\t4500\n"
118 "InstallServices\t\t5000\n"
119 "InstallFinalize\t\t6600\n"
120 "InstallInitialize\t\t1500\n"
121 "InstallValidate\t\t1400\n"
122 "LaunchConditions\t\t100\n"
123 "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
124
125 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
126 "i2\ti4\tL64\tS255\tS32\tS72\n"
127 "Media\tDiskId\n"
128 "1\t3\t\t\tDISK1\t\n"
129 "2\t5\t\tmsitest.cab\tDISK2\t\n";
130
131 static const CHAR property_dat[] = "Property\tValue\n"
132 "s72\tl0\n"
133 "Property\tProperty\n"
134 "DefaultUIFont\tDlgFont8\n"
135 "HASUIRUN\t0\n"
136 "INSTALLLEVEL\t3\n"
137 "InstallMode\tTypical\n"
138 "Manufacturer\tWine\n"
139 "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
140 "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
141 "ProductID\tnone\n"
142 "ProductLanguage\t1033\n"
143 "ProductName\tMSITEST\n"
144 "ProductVersion\t1.1.1\n"
145 "PROMPTROLLBACKCOST\tP\n"
146 "Setup\tSetup\n"
147 "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
148 "AdminProperties\tPOSTADMIN\n"
149 "ROOTDRIVE\tC:\\\n"
150 "SERVNAME\tTestService\n"
151 "SERVDISP\tTestServiceDisp\n";
152
153 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
154 "s72\ti2\tl255\tL255\tL0\ts72\n"
155 "Registry\tRegistry\n"
156 "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
157 "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
158 "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
159 "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
160
161 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
162 "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
163 "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
164 "ServiceInstall\tServiceInstall\n"
165 "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
166
167 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
168 "s72\tl255\ti2\tL255\tI2\ts72\n"
169 "ServiceControl\tServiceControl\n"
170 "ServiceControl\tTestService\t8\t\t0\tservice_comp";
171
172 /* tables for test_continuouscabs */
173 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
174 "s72\tS38\ts72\ti2\tS255\tS72\n"
175 "Component\tComponent\n"
176 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
177 "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
178 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
179
180 static const CHAR cc2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
181 "s72\tS38\ts72\ti2\tS255\tS72\n"
182 "Component\tComponent\n"
183 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
184 "augustus\t\tMSITESTDIR\t0\t0\taugustus\n"
185 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
186
187 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
188 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
189 "Feature\tFeature\n"
190 "feature\t\t\t\t2\t1\tTARGETDIR\t0";
191
192 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
193 "s38\ts72\n"
194 "FeatureComponents\tFeature_\tComponent_\n"
195 "feature\tmaximus\n"
196 "feature\taugustus\n"
197 "feature\tcaesar";
198
199 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
200 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
201 "File\tFile\n"
202 "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
203 "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
204 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
205
206 static const CHAR cc2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
207 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
208 "File\tFile\n"
209 "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
210 "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
211 "tiberius\tmaximus\ttiberius\t500\t\t\t16384\t3\n"
212 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
213
214 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
215 "i2\ti4\tL64\tS255\tS32\tS72\n"
216 "Media\tDiskId\n"
217 "1\t10\t\ttest1.cab\tDISK1\t\n"
218 "2\t2\t\ttest2.cab\tDISK2\t\n"
219 "3\t12\t\ttest3.cab\tDISK3\t\n";
220
221 static const CHAR co_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
222 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
223 "File\tFile\n"
224 "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
225 "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
226 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
227
228 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
229 "i2\ti4\tL64\tS255\tS32\tS72\n"
230 "Media\tDiskId\n"
231 "1\t10\t\ttest1.cab\tDISK1\t\n"
232 "2\t2\t\ttest2.cab\tDISK2\t\n"
233 "3\t3\t\ttest3.cab\tDISK3\t\n";
234
235 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
236 "i2\ti4\tL64\tS255\tS32\tS72\n"
237 "Media\tDiskId\n"
238 "1\t10\t\ttest1.cab\tDISK1\t\n"
239 "2\t12\t\ttest3.cab\tDISK3\t\n"
240 "3\t2\t\ttest2.cab\tDISK2\t\n";
241
242 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
243 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
244 "File\tFile\n"
245 "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
246 "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
247 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
248
249 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
250 "i2\ti4\tL64\tS255\tS32\tS72\n"
251 "Media\tDiskId\n"
252 "1\t3\t\ttest1.cab\tDISK1\t\n";
253
254 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
255 "i2\ti4\tL64\tS255\tS32\tS72\n"
256 "Media\tDiskId\n"
257 "1\t2\t\ttest1.cab\tDISK1\t\n"
258 "2\t2\t\ttest2.cab\tDISK2\t\n"
259 "3\t12\t\ttest3.cab\tDISK3\t\n";
260
261 /* tables for test_uiLevelFlags */
262 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
263 "s72\tS38\ts72\ti2\tS255\tS72\n"
264 "Component\tComponent\n"
265 "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
266 "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
267 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
268
269 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
270 "s72\tS255\tI2\n"
271 "InstallUISequence\tAction\n"
272 "SetUIProperty\t\t5\n"
273 "ExecuteAction\t\t1100\n";
274
275 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
276 "s72\ti2\tS64\tS0\tS255\n"
277 "CustomAction\tAction\n"
278 "SetUIProperty\t51\tHASUIRUN\t1\t\n";
279
280 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
281 "s72\tS38\ts72\ti2\tS255\tS72\n"
282 "Component\tComponent\n"
283 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
284
285 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
286 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
287 "Feature\tFeature\n"
288 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
289 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
290
291 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
292 "s38\ts72\n"
293 "FeatureComponents\tFeature_\tComponent_\n"
294 "feature\tmaximus\n"
295 "montecristo\tmaximus";
296
297 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
298 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
299 "File\tFile\n"
300 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
301
302 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
303 "i2\ti4\tL64\tS255\tS32\tS72\n"
304 "Media\tDiskId\n"
305 "1\t1\t\t\tDISK1\t\n";
306
307 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
308 "s72\tS255\tI2\n"
309 "InstallExecuteSequence\tAction\n"
310 "AllocateRegistrySpace\tNOT Installed\t1550\n"
311 "CostFinalize\t\t1000\n"
312 "CostInitialize\t\t800\n"
313 "FileCost\t\t900\n"
314 "InstallFiles\t\t4000\n"
315 "InstallFinalize\t\t6600\n"
316 "InstallInitialize\t\t1500\n"
317 "InstallValidate\t\t1400\n"
318 "LaunchConditions\t\t100\n"
319 "SetDirProperty\t\t950";
320
321 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
322 "s72\ti2\tS64\tS0\tS255\n"
323 "CustomAction\tAction\n"
324 "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
325
326 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
327 "s72\tS38\ts72\ti2\tS255\tS72\n"
328 "Component\tComponent\n"
329 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
330 "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
331 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
332 "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
333
334 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
335 "s38\ts72\n"
336 "FeatureComponents\tFeature_\tComponent_\n"
337 "feature\tmaximus\n"
338 "feature\taugustus\n"
339 "feature\tcaesar\n"
340 "feature\tgaius";
341
342 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
343 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
344 "File\tFile\n"
345 "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
346 "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
347 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
348 "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
349
350 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
351 "i2\ti4\tL64\tS255\tS32\tS72\n"
352 "Media\tDiskId\n"
353 "1\t1\t\ttest1.cab\tDISK1\t\n"
354 "2\t2\t\ttest2.cab\tDISK2\t\n"
355 "3\t12\t\ttest3.cab\tDISK3\t\n";
356
357 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
358 "s72\tS255\tI2\n"
359 "InstallExecuteSequence\tAction\n"
360 "CostFinalize\t\t1000\n"
361 "CostInitialize\t\t800\n"
362 "FileCost\t\t900\n"
363 "InstallFiles\t\t4000\n"
364 "InstallServices\t\t5000\n"
365 "InstallFinalize\t\t6600\n"
366 "InstallInitialize\t\t1500\n"
367 "RunInstall\t\t1600\n"
368 "InstallValidate\t\t1400\n"
369 "LaunchConditions\t\t100";
370
371 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
372 "s72\ti2\tS64\tS0\tS255\n"
373 "CustomAction\tAction\n"
374 "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
375
376 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
377 "s72\tS38\ts72\ti2\tS255\tS72\n"
378 "Component\tComponent\n"
379 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
380
381 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
382 "s72\tS38\ts72\ti2\tS255\tS72\n"
383 "Component\tComponent\n"
384 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
385
386 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
387 "s38\ts72\n"
388 "FeatureComponents\tFeature_\tComponent_\n"
389 "feature\taugustus";
390
391 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
392 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
393 "File\tFile\n"
394 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
395
396 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
397 "s72\ti2\tS64\tS0\tS255\n"
398 "CustomAction\tAction\n"
399 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
400
401 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
402 "s72\tS255\tI2\n"
403 "InstallExecuteSequence\tAction\n"
404 "CostFinalize\t\t1000\n"
405 "CostInitialize\t\t800\n"
406 "FileCost\t\t900\n"
407 "SetFolderProp\t\t950\n"
408 "InstallFiles\t\t4000\n"
409 "InstallServices\t\t5000\n"
410 "InstallFinalize\t\t6600\n"
411 "InstallInitialize\t\t1500\n"
412 "InstallValidate\t\t1400\n"
413 "LaunchConditions\t\t100";
414
415 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
416 "s72\tS255\tI2\n"
417 "InstallUISequence\tAction\n"
418 "CostInitialize\t\t800\n"
419 "FileCost\t\t900\n"
420 "CostFinalize\t\t1000\n"
421 "ExecuteAction\t\t1100\n";
422
423 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
424 "s72\tS255\tI2\n"
425 "InstallExecuteSequence\tAction\n"
426 "ValidateProductID\t\t700\n"
427 "CostInitialize\t\t800\n"
428 "FileCost\t\t900\n"
429 "CostFinalize\t\t1000\n"
430 "InstallValidate\t\t1400\n"
431 "InstallInitialize\t\t1500\n"
432 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
433 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
434 "RemoveFiles\t\t3500\n"
435 "InstallFiles\t\t4000\n"
436 "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
437 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
438 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
439 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
440 "InstallFinalize\t\t6600";
441
442 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
443 "s72\tS38\ts72\ti2\tS255\tS72\n"
444 "Component\tComponent\n"
445 "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
446
447 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
448 "s72\tS38\ts72\ti2\tS255\tS72\n"
449 "Component\tComponent\n"
450 "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
451
452 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
453 "s72\tS38\ts72\ti2\tS255\tS72\n"
454 "Component\tComponent\n"
455 "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
456
457 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
458 "s72\ti2\tS64\tS0\tS255\n"
459 "CustomAction\tAction\n"
460 "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
461
462 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
463 "s72\tS255\tI2\n"
464 "AdminExecuteSequence\tAction\n"
465 "CostFinalize\t\t1000\n"
466 "CostInitialize\t\t800\n"
467 "FileCost\t\t900\n"
468 "SetPOSTADMIN\t\t950\n"
469 "InstallFiles\t\t4000\n"
470 "InstallFinalize\t\t6600\n"
471 "InstallInitialize\t\t1500\n"
472 "InstallValidate\t\t1400\n"
473 "LaunchConditions\t\t100";
474
475 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
476 "s72\tS38\ts72\ti2\tS255\tS72\n"
477 "Component\tComponent\n"
478 "augustus\t\tMSITESTDIR\t0\tMYPROP=2718\taugustus\n";
479
480 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
481 "s72\tS38\ts72\ti2\tS255\tS72\n"
482 "Component\tComponent\n"
483 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
484 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
485 "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
486
487 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
488 "s38\ts72\n"
489 "FeatureComponents\tFeature_\tComponent_\n"
490 "feature\thydrogen\n"
491 "feature\thelium\n"
492 "feature\tlithium";
493
494 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
495 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
496 "File\tFile\n"
497 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
498 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
499 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
500
501 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
502 "s72\tS255\tI2\n"
503 "InstallExecuteSequence\tAction\n"
504 "ValidateProductID\t\t700\n"
505 "CostInitialize\t\t800\n"
506 "FileCost\t\t900\n"
507 "CostFinalize\t\t1000\n"
508 "InstallValidate\t\t1400\n"
509 "InstallInitialize\t\t1500\n"
510 "ProcessComponents\t\t1600\n"
511 "UnpublishFeatures\t\t1800\n"
512 "RemoveFiles\t\t3500\n"
513 "InstallFiles\t\t4000\n"
514 "RegisterProduct\t\t6100\n"
515 "PublishFeatures\t\t6300\n"
516 "PublishProduct\t\t6400\n"
517 "InstallFinalize\t\t6600";
518
519 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
520 "s72\ts72\tS255\ts72\tI2\n"
521 "RemoveFile\tFileKey\n"
522 "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
523 "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
524 "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
525 "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
526 "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
527 "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
528 "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
529 "block\thelium\tblock\tMSITESTDIR\t3\n"
530 "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n";
531
532 static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
533 "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
534 "MoveFile\tFileKey\n"
535 "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
536 "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
537 "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
538 "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
539 "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
540 "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
541 "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
542 "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
543 "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
544 "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
545 "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
546 "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
547 "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
548 "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
549 "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
550 "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
551 "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
552
553 static const CHAR mc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
554 "s72\tS38\ts72\ti2\tS255\tS72\n"
555 "Component\tComponent\n"
556 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
557 "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
558 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
559 "gaius\t\tMSITESTDIR\t0\tGAIUS=1\tgaius\n";
560
561 static const CHAR mc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
562 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
563 "File\tFile\n"
564 "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
565 "augustus\taugustus\taugustus\t500\t\t\t0\t2\n"
566 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3\n"
567 "gaius\tgaius\tgaius\t500\t\t\t16384\t4";
568
569 static const CHAR mc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
570 "i2\ti4\tL64\tS255\tS32\tS72\n"
571 "Media\tDiskId\n"
572 "1\t1\t\ttest1.cab\tDISK1\t\n"
573 "2\t2\t\ttest2.cab\tDISK2\t\n"
574 "3\t3\t\ttest3.cab\tDISK3\t\n"
575 "4\t4\t\ttest3.cab\tDISK3\t\n";
576
577 static const CHAR mc_file_hash_dat[] = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"
578 "s72\ti2\ti4\ti4\ti4\ti4\n"
579 "MsiFileHash\tFile_\n"
580 "caesar\t0\t850433704\t-241429251\t675791761\t-1221108824";
581
582 static const CHAR df_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
583 "s72\tS72\tl255\n"
584 "Directory\tDirectory\n"
585 "THIS\tMSITESTDIR\tthis\n"
586 "DOESNOT\tTHIS\tdoesnot\n"
587 "NONEXISTENT\tDOESNOT\texist\n"
588 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
589 "ProgramFilesFolder\tTARGETDIR\t.\n"
590 "TARGETDIR\t\tSourceDir";
591
592 static const CHAR df_duplicate_file_dat[] = "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
593 "s72\ts72\ts72\tS255\tS72\n"
594 "DuplicateFile\tFileKey\n"
595 "maximus\tmaximus\tmaximus\taugustus\t\n"
596 "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n";
597
598 static const CHAR wrv_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\t\taugustus\n";
602
603 static const CHAR wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
604 "s72\ti2\tl255\tL255\tL0\ts72\n"
605 "Registry\tRegistry\n"
606 "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus";
607
608 static const CHAR ca51_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\tMYPROP=42\taugustus\n";
612
613 static const CHAR ca51_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
614 "s72\tS255\tI2\n"
615 "InstallExecuteSequence\tAction\n"
616 "ValidateProductID\t\t700\n"
617 "GoodSetProperty\t\t725\n"
618 "BadSetProperty\t\t750\n"
619 "CostInitialize\t\t800\n"
620 "FileCost\t\t900\n"
621 "CostFinalize\t\t1000\n"
622 "InstallValidate\t\t1400\n"
623 "InstallInitialize\t\t1500\n"
624 "InstallFiles\t\t4000\n"
625 "InstallFinalize\t\t6600";
626
627 static const CHAR ca51_custom_action_dat[] = "Action\tType\tSource\tTarget\n"
628 "s72\ti2\tS64\tS0\n"
629 "CustomAction\tAction\n"
630 "GoodSetProperty\t51\tMYPROP\t42\n"
631 "BadSetProperty\t51\t\tMYPROP\n";
632
633 typedef struct _msi_table
634 {
635 const CHAR *filename;
636 const CHAR *data;
637 int size;
638 } msi_table;
639
640 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
641
642 static const msi_table tables[] =
643 {
644 ADD_TABLE(component),
645 ADD_TABLE(directory),
646 ADD_TABLE(feature),
647 ADD_TABLE(feature_comp),
648 ADD_TABLE(file),
649 ADD_TABLE(install_exec_seq),
650 ADD_TABLE(media),
651 ADD_TABLE(property),
652 ADD_TABLE(registry),
653 ADD_TABLE(service_install),
654 ADD_TABLE(service_control)
655 };
656
657 static const msi_table cc_tables[] =
658 {
659 ADD_TABLE(cc_component),
660 ADD_TABLE(directory),
661 ADD_TABLE(cc_feature),
662 ADD_TABLE(cc_feature_comp),
663 ADD_TABLE(cc_file),
664 ADD_TABLE(install_exec_seq),
665 ADD_TABLE(cc_media),
666 ADD_TABLE(property),
667 };
668
669 static const msi_table cc2_tables[] =
670 {
671 ADD_TABLE(cc2_component),
672 ADD_TABLE(directory),
673 ADD_TABLE(cc_feature),
674 ADD_TABLE(cc_feature_comp),
675 ADD_TABLE(cc2_file),
676 ADD_TABLE(install_exec_seq),
677 ADD_TABLE(cc_media),
678 ADD_TABLE(property),
679 };
680
681 static const msi_table co_tables[] =
682 {
683 ADD_TABLE(cc_component),
684 ADD_TABLE(directory),
685 ADD_TABLE(cc_feature),
686 ADD_TABLE(cc_feature_comp),
687 ADD_TABLE(co_file),
688 ADD_TABLE(install_exec_seq),
689 ADD_TABLE(co_media),
690 ADD_TABLE(property),
691 };
692
693 static const msi_table co2_tables[] =
694 {
695 ADD_TABLE(cc_component),
696 ADD_TABLE(directory),
697 ADD_TABLE(cc_feature),
698 ADD_TABLE(cc_feature_comp),
699 ADD_TABLE(cc_file),
700 ADD_TABLE(install_exec_seq),
701 ADD_TABLE(co2_media),
702 ADD_TABLE(property),
703 };
704
705 static const msi_table mm_tables[] =
706 {
707 ADD_TABLE(cc_component),
708 ADD_TABLE(directory),
709 ADD_TABLE(cc_feature),
710 ADD_TABLE(cc_feature_comp),
711 ADD_TABLE(mm_file),
712 ADD_TABLE(install_exec_seq),
713 ADD_TABLE(mm_media),
714 ADD_TABLE(property),
715 };
716
717 static const msi_table ss_tables[] =
718 {
719 ADD_TABLE(cc_component),
720 ADD_TABLE(directory),
721 ADD_TABLE(cc_feature),
722 ADD_TABLE(cc_feature_comp),
723 ADD_TABLE(cc_file),
724 ADD_TABLE(install_exec_seq),
725 ADD_TABLE(ss_media),
726 ADD_TABLE(property),
727 };
728
729 static const msi_table ui_tables[] =
730 {
731 ADD_TABLE(ui_component),
732 ADD_TABLE(directory),
733 ADD_TABLE(cc_feature),
734 ADD_TABLE(cc_feature_comp),
735 ADD_TABLE(cc_file),
736 ADD_TABLE(install_exec_seq),
737 ADD_TABLE(ui_install_ui_seq),
738 ADD_TABLE(ui_custom_action),
739 ADD_TABLE(cc_media),
740 ADD_TABLE(property),
741 };
742
743 static const msi_table rof_tables[] =
744 {
745 ADD_TABLE(rof_component),
746 ADD_TABLE(directory),
747 ADD_TABLE(rof_feature),
748 ADD_TABLE(rof_feature_comp),
749 ADD_TABLE(rof_file),
750 ADD_TABLE(install_exec_seq),
751 ADD_TABLE(rof_media),
752 ADD_TABLE(property),
753 };
754
755 static const msi_table sdp_tables[] =
756 {
757 ADD_TABLE(rof_component),
758 ADD_TABLE(directory),
759 ADD_TABLE(rof_feature),
760 ADD_TABLE(rof_feature_comp),
761 ADD_TABLE(rof_file),
762 ADD_TABLE(sdp_install_exec_seq),
763 ADD_TABLE(sdp_custom_action),
764 ADD_TABLE(rof_media),
765 ADD_TABLE(property),
766 };
767
768 static const msi_table cie_tables[] =
769 {
770 ADD_TABLE(cie_component),
771 ADD_TABLE(directory),
772 ADD_TABLE(cc_feature),
773 ADD_TABLE(cie_feature_comp),
774 ADD_TABLE(cie_file),
775 ADD_TABLE(install_exec_seq),
776 ADD_TABLE(cie_media),
777 ADD_TABLE(property),
778 };
779
780 static const msi_table ci_tables[] =
781 {
782 ADD_TABLE(ci_component),
783 ADD_TABLE(directory),
784 ADD_TABLE(rof_feature),
785 ADD_TABLE(rof_feature_comp),
786 ADD_TABLE(rof_file),
787 ADD_TABLE(ci_install_exec_seq),
788 ADD_TABLE(rof_media),
789 ADD_TABLE(property),
790 ADD_TABLE(ci_custom_action),
791 };
792
793 static const msi_table ci2_tables[] =
794 {
795 ADD_TABLE(ci2_component),
796 ADD_TABLE(directory),
797 ADD_TABLE(rof_feature),
798 ADD_TABLE(ci2_feature_comp),
799 ADD_TABLE(ci2_file),
800 ADD_TABLE(install_exec_seq),
801 ADD_TABLE(rof_media),
802 ADD_TABLE(property),
803 };
804
805 static const msi_table spf_tables[] =
806 {
807 ADD_TABLE(ci_component),
808 ADD_TABLE(directory),
809 ADD_TABLE(rof_feature),
810 ADD_TABLE(rof_feature_comp),
811 ADD_TABLE(rof_file),
812 ADD_TABLE(spf_install_exec_seq),
813 ADD_TABLE(rof_media),
814 ADD_TABLE(property),
815 ADD_TABLE(spf_custom_action),
816 ADD_TABLE(spf_install_ui_seq),
817 };
818
819 static const msi_table pp_tables[] =
820 {
821 ADD_TABLE(ci_component),
822 ADD_TABLE(directory),
823 ADD_TABLE(rof_feature),
824 ADD_TABLE(rof_feature_comp),
825 ADD_TABLE(rof_file),
826 ADD_TABLE(pp_install_exec_seq),
827 ADD_TABLE(rof_media),
828 ADD_TABLE(property),
829 };
830
831 static const msi_table tp_tables[] =
832 {
833 ADD_TABLE(tp_component),
834 ADD_TABLE(directory),
835 ADD_TABLE(rof_feature),
836 ADD_TABLE(ci2_feature_comp),
837 ADD_TABLE(ci2_file),
838 ADD_TABLE(install_exec_seq),
839 ADD_TABLE(rof_media),
840 ADD_TABLE(property),
841 };
842
843 static const msi_table cwd_tables[] =
844 {
845 ADD_TABLE(cwd_component),
846 ADD_TABLE(directory),
847 ADD_TABLE(rof_feature),
848 ADD_TABLE(ci2_feature_comp),
849 ADD_TABLE(ci2_file),
850 ADD_TABLE(install_exec_seq),
851 ADD_TABLE(rof_media),
852 ADD_TABLE(property),
853 };
854
855 static const msi_table adm_tables[] =
856 {
857 ADD_TABLE(adm_component),
858 ADD_TABLE(directory),
859 ADD_TABLE(rof_feature),
860 ADD_TABLE(ci2_feature_comp),
861 ADD_TABLE(ci2_file),
862 ADD_TABLE(install_exec_seq),
863 ADD_TABLE(rof_media),
864 ADD_TABLE(property),
865 ADD_TABLE(adm_custom_action),
866 ADD_TABLE(adm_admin_exec_seq),
867 };
868
869 static const msi_table amp_tables[] =
870 {
871 ADD_TABLE(amp_component),
872 ADD_TABLE(directory),
873 ADD_TABLE(rof_feature),
874 ADD_TABLE(ci2_feature_comp),
875 ADD_TABLE(ci2_file),
876 ADD_TABLE(install_exec_seq),
877 ADD_TABLE(rof_media),
878 ADD_TABLE(property),
879 };
880
881 static const msi_table rem_tables[] =
882 {
883 ADD_TABLE(rem_component),
884 ADD_TABLE(directory),
885 ADD_TABLE(rof_feature),
886 ADD_TABLE(rem_feature_comp),
887 ADD_TABLE(rem_file),
888 ADD_TABLE(rem_install_exec_seq),
889 ADD_TABLE(rof_media),
890 ADD_TABLE(property),
891 ADD_TABLE(rem_remove_files),
892 };
893
894 static const msi_table mov_tables[] =
895 {
896 ADD_TABLE(cwd_component),
897 ADD_TABLE(directory),
898 ADD_TABLE(rof_feature),
899 ADD_TABLE(ci2_feature_comp),
900 ADD_TABLE(ci2_file),
901 ADD_TABLE(install_exec_seq),
902 ADD_TABLE(rof_media),
903 ADD_TABLE(property),
904 ADD_TABLE(mov_move_file),
905 };
906
907 static const msi_table mc_tables[] =
908 {
909 ADD_TABLE(mc_component),
910 ADD_TABLE(directory),
911 ADD_TABLE(cc_feature),
912 ADD_TABLE(cie_feature_comp),
913 ADD_TABLE(mc_file),
914 ADD_TABLE(install_exec_seq),
915 ADD_TABLE(mc_media),
916 ADD_TABLE(property),
917 ADD_TABLE(mc_file_hash),
918 };
919
920 static const msi_table df_tables[] =
921 {
922 ADD_TABLE(rof_component),
923 ADD_TABLE(df_directory),
924 ADD_TABLE(rof_feature),
925 ADD_TABLE(rof_feature_comp),
926 ADD_TABLE(rof_file),
927 ADD_TABLE(install_exec_seq),
928 ADD_TABLE(rof_media),
929 ADD_TABLE(property),
930 ADD_TABLE(df_duplicate_file),
931 };
932
933 static const msi_table wrv_tables[] =
934 {
935 ADD_TABLE(wrv_component),
936 ADD_TABLE(directory),
937 ADD_TABLE(rof_feature),
938 ADD_TABLE(ci2_feature_comp),
939 ADD_TABLE(ci2_file),
940 ADD_TABLE(install_exec_seq),
941 ADD_TABLE(rof_media),
942 ADD_TABLE(property),
943 ADD_TABLE(wrv_registry),
944 };
945
946 static const msi_table sf_tables[] =
947 {
948 ADD_TABLE(wrv_component),
949 ADD_TABLE(directory),
950 ADD_TABLE(rof_feature),
951 ADD_TABLE(ci2_feature_comp),
952 ADD_TABLE(ci2_file),
953 ADD_TABLE(install_exec_seq),
954 ADD_TABLE(rof_media),
955 ADD_TABLE(property),
956 };
957
958 static const msi_table ca51_tables[] =
959 {
960 ADD_TABLE(ca51_component),
961 ADD_TABLE(directory),
962 ADD_TABLE(rof_feature),
963 ADD_TABLE(ci2_feature_comp),
964 ADD_TABLE(ci2_file),
965 ADD_TABLE(ca51_install_exec_seq),
966 ADD_TABLE(rof_media),
967 ADD_TABLE(property),
968 ADD_TABLE(ca51_custom_action),
969 };
970
971 /* cabinet definitions */
972
973 /* make the max size large so there is only one cab file */
974 #define MEDIA_SIZE 0x7FFFFFFF
975 #define FOLDER_THRESHOLD 900000
976
977 /* the FCI callbacks */
978
979 static void *mem_alloc(ULONG cb)
980 {
981 return HeapAlloc(GetProcessHeap(), 0, cb);
982 }
983
984 static void mem_free(void *memory)
985 {
986 HeapFree(GetProcessHeap(), 0, memory);
987 }
988
989 static BOOL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
990 {
991 sprintf(pccab->szCab, pv, pccab->iCab);
992 return TRUE;
993 }
994
995 static long progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
996 {
997 return 0;
998 }
999
1000 static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
1001 BOOL fContinuation, void *pv)
1002 {
1003 return 0;
1004 }
1005
1006 static INT_PTR fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
1007 {
1008 HANDLE handle;
1009 DWORD dwAccess = 0;
1010 DWORD dwShareMode = 0;
1011 DWORD dwCreateDisposition = OPEN_EXISTING;
1012
1013 dwAccess = GENERIC_READ | GENERIC_WRITE;
1014 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
1015 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1016
1017 if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
1018 dwCreateDisposition = OPEN_EXISTING;
1019 else
1020 dwCreateDisposition = CREATE_NEW;
1021
1022 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
1023 dwCreateDisposition, 0, NULL);
1024
1025 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
1026
1027 return (INT_PTR)handle;
1028 }
1029
1030 static UINT fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1031 {
1032 HANDLE handle = (HANDLE)hf;
1033 DWORD dwRead;
1034 BOOL res;
1035
1036 res = ReadFile(handle, memory, cb, &dwRead, NULL);
1037 ok(res, "Failed to ReadFile\n");
1038
1039 return dwRead;
1040 }
1041
1042 static UINT fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1043 {
1044 HANDLE handle = (HANDLE)hf;
1045 DWORD dwWritten;
1046 BOOL res;
1047
1048 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
1049 ok(res, "Failed to WriteFile\n");
1050
1051 return dwWritten;
1052 }
1053
1054 static int fci_close(INT_PTR hf, int *err, void *pv)
1055 {
1056 HANDLE handle = (HANDLE)hf;
1057 ok(CloseHandle(handle), "Failed to CloseHandle\n");
1058
1059 return 0;
1060 }
1061
1062 static long fci_seek(INT_PTR hf, long dist, int seektype, int *err, void *pv)
1063 {
1064 HANDLE handle = (HANDLE)hf;
1065 DWORD ret;
1066
1067 ret = SetFilePointer(handle, dist, NULL, seektype);
1068 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
1069
1070 return ret;
1071 }
1072
1073 static int fci_delete(char *pszFile, int *err, void *pv)
1074 {
1075 BOOL ret = DeleteFileA(pszFile);
1076 ok(ret, "Failed to DeleteFile %s\n", pszFile);
1077
1078 return 0;
1079 }
1080
1081 static void init_functionpointers(void)
1082 {
1083 HMODULE hmsi = GetModuleHandleA("msi.dll");
1084
1085 #define GET_PROC(func) \
1086 p ## func = (void*)GetProcAddress(hmsi, #func); \
1087 if(!p ## func) \
1088 trace("GetProcAddress(%s) failed\n", #func);
1089
1090 GET_PROC(MsiQueryComponentStateA);
1091 GET_PROC(MsiSourceListEnumSourcesA);
1092 GET_PROC(MsiSourceListGetInfoA);
1093
1094 #undef GET_PROC
1095 }
1096
1097 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
1098 {
1099 CHAR buffer[0x20];
1100 UINT r;
1101 DWORD sz;
1102
1103 sz = sizeof buffer;
1104 r = MsiRecordGetString(rec, field, buffer, &sz);
1105 return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1106 }
1107
1108 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
1109 {
1110 LPSTR tempname;
1111
1112 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
1113 GetTempFileNameA(".", "xx", 0, tempname);
1114
1115 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
1116 {
1117 lstrcpyA(pszTempName, tempname);
1118 HeapFree(GetProcessHeap(), 0, tempname);
1119 return TRUE;
1120 }
1121
1122 HeapFree(GetProcessHeap(), 0, tempname);
1123
1124 return FALSE;
1125 }
1126
1127 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
1128 USHORT *pattribs, int *err, void *pv)
1129 {
1130 BY_HANDLE_FILE_INFORMATION finfo;
1131 FILETIME filetime;
1132 HANDLE handle;
1133 DWORD attrs;
1134 BOOL res;
1135
1136 handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
1137 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1138
1139 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
1140
1141 res = GetFileInformationByHandle(handle, &finfo);
1142 ok(res, "Expected GetFileInformationByHandle to succeed\n");
1143
1144 FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
1145 FileTimeToDosDateTime(&filetime, pdate, ptime);
1146
1147 attrs = GetFileAttributes(pszName);
1148 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
1149
1150 return (INT_PTR)handle;
1151 }
1152
1153 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
1154 {
1155 char path[MAX_PATH];
1156 char filename[MAX_PATH];
1157
1158 lstrcpyA(path, CURR_DIR);
1159 lstrcatA(path, "\\");
1160 lstrcatA(path, file);
1161
1162 lstrcpyA(filename, file);
1163
1164 return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
1165 progress, get_open_info, compress);
1166 }
1167
1168 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
1169 {
1170 ZeroMemory(pCabParams, sizeof(CCAB));
1171
1172 pCabParams->cb = max_size;
1173 pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
1174 pCabParams->setID = 0xbeef;
1175 pCabParams->iCab = 1;
1176 lstrcpyA(pCabParams->szCabPath, CURR_DIR);
1177 lstrcatA(pCabParams->szCabPath, "\\");
1178 lstrcpyA(pCabParams->szCab, name);
1179 }
1180
1181 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
1182 {
1183 CCAB cabParams;
1184 LPCSTR ptr;
1185 HFCI hfci;
1186 ERF erf;
1187 BOOL res;
1188
1189 set_cab_parameters(&cabParams, name, max_size);
1190
1191 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1192 fci_read, fci_write, fci_close, fci_seek, fci_delete,
1193 get_temp_file, &cabParams, NULL);
1194
1195 ok(hfci != NULL, "Failed to create an FCI context\n");
1196
1197 ptr = files;
1198 while (*ptr)
1199 {
1200 res = add_file(hfci, ptr, tcompTYPE_MSZIP);
1201 ok(res, "Failed to add file: %s\n", ptr);
1202 ptr += lstrlen(ptr) + 1;
1203 }
1204
1205 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1206 ok(res, "Failed to flush the cabinet\n");
1207
1208 res = FCIDestroy(hfci);
1209 ok(res, "Failed to destroy the cabinet\n");
1210 }
1211
1212 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1213 {
1214 HKEY hkey;
1215 DWORD type, size;
1216
1217 if (RegOpenKey(HKEY_LOCAL_MACHINE,
1218 "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1219 return FALSE;
1220
1221 size = MAX_PATH;
1222 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1223 RegCloseKey(hkey);
1224 return FALSE;
1225 }
1226
1227 size = MAX_PATH;
1228 if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1229 RegCloseKey(hkey);
1230 return FALSE;
1231 }
1232
1233 RegCloseKey(hkey);
1234 return TRUE;
1235 }
1236
1237 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1238 {
1239 HANDLE file;
1240 DWORD written;
1241
1242 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1243 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1244 WriteFile(file, data, strlen(data), &written, NULL);
1245
1246 if (size)
1247 {
1248 SetFilePointer(file, size, NULL, FILE_BEGIN);
1249 SetEndOfFile(file);
1250 }
1251
1252 CloseHandle(file);
1253 }
1254
1255 #define create_file(name, size) create_file_data(name, name, size)
1256
1257 static void create_test_files(void)
1258 {
1259 CreateDirectoryA("msitest", NULL);
1260 create_file("msitest\\one.txt", 100);
1261 CreateDirectoryA("msitest\\first", NULL);
1262 create_file("msitest\\first\\two.txt", 100);
1263 CreateDirectoryA("msitest\\second", NULL);
1264 create_file("msitest\\second\\three.txt", 100);
1265
1266 create_file("four.txt", 100);
1267 create_file("five.txt", 100);
1268 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1269
1270 create_file("msitest\\filename", 100);
1271 create_file("msitest\\service.exe", 100);
1272
1273 DeleteFileA("four.txt");
1274 DeleteFileA("five.txt");
1275 }
1276
1277 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1278 {
1279 CHAR path[MAX_PATH];
1280
1281 lstrcpyA(path, PROG_FILES_DIR);
1282 lstrcatA(path, "\\");
1283 lstrcatA(path, rel_path);
1284
1285 if (is_file)
1286 return DeleteFileA(path);
1287 else
1288 return RemoveDirectoryA(path);
1289 }
1290
1291 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1292 {
1293 CHAR path[MAX_PATH];
1294
1295 lstrcpyA(path, COMMON_FILES_DIR);
1296 lstrcatA(path, "\\");
1297 lstrcatA(path, rel_path);
1298
1299 if (is_file)
1300 return DeleteFileA(path);
1301 else
1302 return RemoveDirectoryA(path);
1303 }
1304
1305 static void delete_test_files(void)
1306 {
1307 DeleteFileA("msitest.msi");
1308 DeleteFileA("msitest.cab");
1309 DeleteFileA("msitest\\second\\three.txt");
1310 DeleteFileA("msitest\\first\\two.txt");
1311 DeleteFileA("msitest\\one.txt");
1312 DeleteFileA("msitest\\service.exe");
1313 DeleteFileA("msitest\\filename");
1314 RemoveDirectoryA("msitest\\second");
1315 RemoveDirectoryA("msitest\\first");
1316 RemoveDirectoryA("msitest");
1317 }
1318
1319 static void write_file(const CHAR *filename, const char *data, int data_size)
1320 {
1321 DWORD size;
1322
1323 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1324 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1325
1326 WriteFile(hf, data, data_size, &size, NULL);
1327 CloseHandle(hf);
1328 }
1329
1330 static void write_msi_summary_info(MSIHANDLE db)
1331 {
1332 MSIHANDLE summary;
1333 UINT r;
1334
1335 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1337
1338 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1340
1341 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1342 "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1344
1345 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1347
1348 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1350
1351 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1353
1354 /* write the summary changes back to the stream */
1355 r = MsiSummaryInfoPersist(summary);
1356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1357
1358 MsiCloseHandle(summary);
1359 }
1360
1361 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1362 {
1363 MSIHANDLE db;
1364 UINT r;
1365 int j;
1366
1367 r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1369
1370 /* import the tables into the database */
1371 for (j = 0; j < num_tables; j++)
1372 {
1373 const msi_table *table = &tables[j];
1374
1375 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1376
1377 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1379
1380 DeleteFileA(table->filename);
1381 }
1382
1383 write_msi_summary_info(db);
1384
1385 r = MsiDatabaseCommit(db);
1386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1387
1388 MsiCloseHandle(db);
1389 }
1390
1391 static void check_service_is_installed(void)
1392 {
1393 SC_HANDLE scm, service;
1394 BOOL res;
1395
1396 scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1397 ok(scm != NULL, "Failed to open the SC Manager\n");
1398
1399 service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1400 ok(service != NULL, "Failed to open TestService\n");
1401
1402 res = DeleteService(service);
1403 ok(res, "Failed to delete TestService\n");
1404
1405 CloseServiceHandle(service);
1406 CloseServiceHandle(scm);
1407 }
1408
1409 static void test_MsiInstallProduct(void)
1410 {
1411 UINT r;
1412 CHAR path[MAX_PATH];
1413 LONG res;
1414 HKEY hkey;
1415 DWORD num, size, type;
1416 SC_HANDLE scm;
1417
1418 scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
1419 if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1420 {
1421 skip("Services are not implemented, we are most likely on win9x\n");
1422 return;
1423 }
1424 CloseServiceHandle(scm);
1425
1426 create_test_files();
1427 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1428
1429 r = MsiInstallProductA(msifile, NULL);
1430 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1431
1432 ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1433 ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1434 ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1435 ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1436 ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1437 ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1438 ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1439 ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1440 ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1441 ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1442 ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1443 ok(delete_pf("msitest", FALSE), "File not installed\n");
1444
1445 res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1447
1448 size = MAX_PATH;
1449 type = REG_SZ;
1450 res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1451 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1452 ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1453
1454 size = MAX_PATH;
1455 type = REG_SZ;
1456 res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1457 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1458
1459 size = sizeof(num);
1460 type = REG_DWORD;
1461 res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1462 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1463 ok(num == 314, "Expected 314, got %d\n", num);
1464
1465 size = MAX_PATH;
1466 type = REG_SZ;
1467 res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1469 ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1470
1471 check_service_is_installed();
1472
1473 RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1474
1475 delete_test_files();
1476 }
1477
1478 static void test_MsiSetComponentState(void)
1479 {
1480 INSTALLSTATE installed, action;
1481 MSIHANDLE package;
1482 char path[MAX_PATH];
1483 UINT r;
1484
1485 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1486
1487 CoInitialize(NULL);
1488
1489 lstrcpy(path, CURR_DIR);
1490 lstrcat(path, "\\");
1491 lstrcat(path, msifile);
1492
1493 r = MsiOpenPackage(path, &package);
1494 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1495
1496 r = MsiDoAction(package, "CostInitialize");
1497 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1498
1499 r = MsiDoAction(package, "FileCost");
1500 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1501
1502 r = MsiDoAction(package, "CostFinalize");
1503 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1504
1505 r = MsiGetComponentState(package, "dangler", &installed, &action);
1506 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1507 ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1508 ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1509
1510 r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1511 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1512
1513 MsiCloseHandle(package);
1514 CoUninitialize();
1515
1516 DeleteFileA(msifile);
1517 }
1518
1519 static void test_packagecoltypes(void)
1520 {
1521 MSIHANDLE hdb, view, rec;
1522 char path[MAX_PATH];
1523 LPCSTR query;
1524 UINT r, count;
1525
1526 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1527
1528 CoInitialize(NULL);
1529
1530 lstrcpy(path, CURR_DIR);
1531 lstrcat(path, "\\");
1532 lstrcat(path, msifile);
1533
1534 r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1536
1537 query = "SELECT * FROM `Media`";
1538 r = MsiDatabaseOpenView( hdb, query, &view );
1539 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1540
1541 r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1542 count = MsiRecordGetFieldCount( rec );
1543 ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1544 ok(count == 6, "Expected 6, got %d\n", count);
1545 ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1546 ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1547 ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1548 ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1549 ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1550 ok(check_record(rec, 6, "Source"), "wrong column label\n");
1551 MsiCloseHandle(rec);
1552
1553 r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1554 count = MsiRecordGetFieldCount( rec );
1555 ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1556 ok(count == 6, "Expected 6, got %d\n", count);
1557 ok(check_record(rec, 1, "i2"), "wrong column label\n");
1558 ok(check_record(rec, 2, "i4"), "wrong column label\n");
1559 ok(check_record(rec, 3, "L64"), "wrong column label\n");
1560 ok(check_record(rec, 4, "S255"), "wrong column label\n");
1561 ok(check_record(rec, 5, "S32"), "wrong column label\n");
1562 ok(check_record(rec, 6, "S72"), "wrong column label\n");
1563
1564 MsiCloseHandle(rec);
1565 MsiCloseHandle(view);
1566 MsiCloseHandle(hdb);
1567 DeleteFile(msifile);
1568 }
1569
1570 static void create_cc_test_files(void)
1571 {
1572 CCAB cabParams;
1573 HFCI hfci;
1574 ERF erf;
1575 static CHAR cab_context[] = "test%d.cab";
1576 BOOL res;
1577
1578 create_file("maximus", 500);
1579 create_file("augustus", 50000);
1580 create_file("tiberius", 500);
1581 create_file("caesar", 500);
1582
1583 set_cab_parameters(&cabParams, "test1.cab", 40000);
1584
1585 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1586 fci_read, fci_write, fci_close, fci_seek, fci_delete,
1587 get_temp_file, &cabParams, cab_context);
1588 ok(hfci != NULL, "Failed to create an FCI context\n");
1589
1590 res = add_file(hfci, "maximus", tcompTYPE_NONE);
1591 ok(res, "Failed to add file maximus\n");
1592
1593 res = add_file(hfci, "augustus", tcompTYPE_NONE);
1594 ok(res, "Failed to add file augustus\n");
1595
1596 res = add_file(hfci, "tiberius", tcompTYPE_NONE);
1597 ok(res, "Failed to add file tiberius\n");
1598
1599 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1600 ok(res, "Failed to flush the cabinet\n");
1601
1602 res = FCIDestroy(hfci);
1603 ok(res, "Failed to destroy the cabinet\n");
1604
1605 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1606
1607 DeleteFile("maximus");
1608 DeleteFile("augustus");
1609 DeleteFile("tiberius");
1610 DeleteFile("caesar");
1611 }
1612
1613 static void delete_cab_files(void)
1614 {
1615 SHFILEOPSTRUCT shfl;
1616 CHAR path[MAX_PATH+10];
1617
1618 lstrcpyA(path, CURR_DIR);
1619 lstrcatA(path, "\\*.cab");
1620 path[strlen(path) + 1] = '\0';
1621
1622 shfl.hwnd = NULL;
1623 shfl.wFunc = FO_DELETE;
1624 shfl.pFrom = path;
1625 shfl.pTo = NULL;
1626 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1627
1628 SHFileOperation(&shfl);
1629 }
1630
1631 static void test_continuouscabs(void)
1632 {
1633 UINT r;
1634
1635 create_cc_test_files();
1636 create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1637
1638 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1639
1640 r = MsiInstallProductA(msifile, NULL);
1641 if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1642 {
1643 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1644 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1645 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1646 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1647 ok(delete_pf("msitest", FALSE), "File not installed\n");
1648 }
1649
1650 delete_cab_files();
1651 DeleteFile(msifile);
1652
1653 create_cc_test_files();
1654 create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
1655
1656 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1657
1658 r = MsiInstallProductA(msifile, NULL);
1659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1660 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1661 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
1662 ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
1663 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1664 ok(delete_pf("msitest", FALSE), "File not installed\n");
1665
1666 delete_cab_files();
1667 DeleteFile(msifile);
1668 }
1669
1670 static void test_caborder(void)
1671 {
1672 UINT r;
1673
1674 create_file("imperator", 100);
1675 create_file("maximus", 500);
1676 create_file("augustus", 50000);
1677 create_file("caesar", 500);
1678
1679 create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1680
1681 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1682
1683 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1684 create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1685 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1686
1687 r = MsiInstallProductA(msifile, NULL);
1688 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1689 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1690 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1691 todo_wine
1692 {
1693 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1694 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1695 }
1696
1697 delete_cab_files();
1698
1699 create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1700 create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1701 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1702
1703 r = MsiInstallProductA(msifile, NULL);
1704 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1705 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1706 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1707 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1708 todo_wine
1709 {
1710 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1711 }
1712
1713 delete_cab_files();
1714 DeleteFile(msifile);
1715
1716 create_cc_test_files();
1717 create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1718
1719 r = MsiInstallProductA(msifile, NULL);
1720 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1721 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1722 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1723 todo_wine
1724 {
1725 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1726 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1727 }
1728
1729 delete_cab_files();
1730 DeleteFile(msifile);
1731
1732 create_cc_test_files();
1733 create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1734
1735 r = MsiInstallProductA(msifile, NULL);
1736 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1737 todo_wine
1738 {
1739 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1740 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1741 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1742 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1743 }
1744
1745 delete_cab_files();
1746 DeleteFile("imperator");
1747 DeleteFile("maximus");
1748 DeleteFile("augustus");
1749 DeleteFile("caesar");
1750 DeleteFile(msifile);
1751 }
1752
1753 static void test_mixedmedia(void)
1754 {
1755 UINT r;
1756
1757 CreateDirectoryA("msitest", NULL);
1758 create_file("msitest\\maximus", 500);
1759 create_file("msitest\\augustus", 500);
1760 create_file("caesar", 500);
1761
1762 create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1763
1764 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1765
1766 create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1767
1768 r = MsiInstallProductA(msifile, NULL);
1769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1770 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1771 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1772 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1773 ok(delete_pf("msitest", FALSE), "File not installed\n");
1774
1775 /* Delete the files in the temp (current) folder */
1776 DeleteFile("msitest\\maximus");
1777 DeleteFile("msitest\\augustus");
1778 RemoveDirectory("msitest");
1779 DeleteFile("caesar");
1780 DeleteFile("test1.cab");
1781 DeleteFile(msifile);
1782 }
1783
1784 static void test_samesequence(void)
1785 {
1786 UINT r;
1787
1788 create_cc_test_files();
1789 create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1790
1791 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1792
1793 r = MsiInstallProductA(msifile, NULL);
1794 if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1795 {
1796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1797 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1798 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1799 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1800 ok(delete_pf("msitest", FALSE), "File not installed\n");
1801 }
1802
1803 delete_cab_files();
1804 DeleteFile(msifile);
1805 }
1806
1807 static void test_uiLevelFlags(void)
1808 {
1809 UINT r;
1810
1811 create_cc_test_files();
1812 create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1813
1814 MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1815
1816 r = MsiInstallProductA(msifile, NULL);
1817 if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1818 {
1819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1820 ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1821 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1822 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1823 ok(delete_pf("msitest", FALSE), "File not installed\n");
1824 }
1825
1826 delete_cab_files();
1827 DeleteFile(msifile);
1828 }
1829
1830 static BOOL file_matches(LPSTR path)
1831 {
1832 CHAR buf[MAX_PATH];
1833 HANDLE file;
1834 DWORD size;
1835
1836 file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1837 NULL, OPEN_EXISTING, 0, NULL);
1838
1839 ZeroMemory(buf, MAX_PATH);
1840 ReadFile(file, buf, 15, &size, NULL);
1841 CloseHandle(file);
1842
1843 return !lstrcmp(buf, "msitest\\maximus");
1844 }
1845
1846 static void test_readonlyfile(void)
1847 {
1848 UINT r;
1849 DWORD size;
1850 HANDLE file;
1851 CHAR path[MAX_PATH];
1852
1853 CreateDirectoryA("msitest", NULL);
1854 create_file("msitest\\maximus", 500);
1855 create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1856
1857 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1858
1859 lstrcpy(path, PROG_FILES_DIR);
1860 lstrcat(path, "\\msitest");
1861 CreateDirectory(path, NULL);
1862
1863 lstrcat(path, "\\maximus");
1864 file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1865 NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1866
1867 WriteFile(file, "readonlyfile", 20, &size, NULL);
1868 CloseHandle(file);
1869
1870 r = MsiInstallProductA(msifile, NULL);
1871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1872 ok(file_matches(path), "Expected file to be overwritten\n");
1873 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1874 ok(delete_pf("msitest", FALSE), "File not installed\n");
1875
1876 /* Delete the files in the temp (current) folder */
1877 DeleteFile("msitest\\maximus");
1878 RemoveDirectory("msitest");
1879 DeleteFile(msifile);
1880 }
1881
1882 static void test_setdirproperty(void)
1883 {
1884 UINT r;
1885
1886 CreateDirectoryA("msitest", NULL);
1887 create_file("msitest\\maximus", 500);
1888 create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1889
1890 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1891
1892 r = MsiInstallProductA(msifile, NULL);
1893 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1894 ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1895 ok(delete_cf("msitest", FALSE), "File not installed\n");
1896
1897 /* Delete the files in the temp (current) folder */
1898 DeleteFile(msifile);
1899 DeleteFile("msitest\\maximus");
1900 RemoveDirectory("msitest");
1901 }
1902
1903 static void test_cabisextracted(void)
1904 {
1905 UINT r;
1906
1907 CreateDirectoryA("msitest", NULL);
1908 create_file("msitest\\gaius", 500);
1909 create_file("maximus", 500);
1910 create_file("augustus", 500);
1911 create_file("caesar", 500);
1912
1913 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1914 create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1915 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1916
1917 create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
1918
1919 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1920
1921 r = MsiInstallProductA(msifile, NULL);
1922 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1923 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1924 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1925 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1926 ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
1927 ok(delete_pf("msitest", FALSE), "File not installed\n");
1928
1929 /* Delete the files in the temp (current) folder */
1930 delete_cab_files();
1931 DeleteFile(msifile);
1932 DeleteFile("maximus");
1933 DeleteFile("augustus");
1934 DeleteFile("caesar");
1935 DeleteFile("msitest\\gaius");
1936 RemoveDirectory("msitest");
1937 }
1938
1939 static void test_concurrentinstall(void)
1940 {
1941 UINT r;
1942 CHAR path[MAX_PATH];
1943
1944 CreateDirectoryA("msitest", NULL);
1945 CreateDirectoryA("msitest\\msitest", NULL);
1946 create_file("msitest\\maximus", 500);
1947 create_file("msitest\\msitest\\augustus", 500);
1948
1949 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
1950
1951 lstrcpyA(path, CURR_DIR);
1952 lstrcatA(path, "\\msitest\\concurrent.msi");
1953 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
1954
1955 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1956
1957 r = MsiInstallProductA(msifile, NULL);
1958 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1959 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1960 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1961 ok(delete_pf("msitest", FALSE), "File not installed\n");
1962
1963 DeleteFile(path);
1964
1965 r = MsiInstallProductA(msifile, NULL);
1966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1967 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1968 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
1969 ok(delete_pf("msitest", FALSE), "File not installed\n");
1970
1971 DeleteFile(msifile);
1972 DeleteFile("msitest\\msitest\\augustus");
1973 DeleteFile("msitest\\maximus");
1974 RemoveDirectory("msitest\\msitest");
1975 RemoveDirectory("msitest");
1976 }
1977
1978 static void test_setpropertyfolder(void)
1979 {
1980 UINT r;
1981
1982 CreateDirectoryA("msitest", NULL);
1983 create_file("msitest\\maximus", 500);
1984
1985 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
1986
1987 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1988
1989 r = MsiInstallProductA(msifile, NULL);
1990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1991 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
1992 ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
1993 ok(delete_pf("msitest", FALSE), "File not installed\n");
1994
1995 /* Delete the files in the temp (current) folder */
1996 DeleteFile(msifile);
1997 DeleteFile("msitest\\maximus");
1998 RemoveDirectory("msitest");
1999 }
2000
2001 static BOOL file_exists(LPCSTR file)
2002 {
2003 return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
2004 }
2005
2006 static BOOL pf_exists(LPCSTR file)
2007 {
2008 CHAR path[MAX_PATH];
2009
2010 lstrcpyA(path, PROG_FILES_DIR);
2011 lstrcatA(path, "\\");
2012 lstrcatA(path, file);
2013
2014 return file_exists(path);
2015 }
2016
2017 static void delete_pfmsitest_files(void)
2018 {
2019 SHFILEOPSTRUCT shfl;
2020 CHAR path[MAX_PATH+11];
2021
2022 lstrcpyA(path, PROG_FILES_DIR);
2023 lstrcatA(path, "\\msitest\\*");
2024 path[strlen(path) + 1] = '\0';
2025
2026 shfl.hwnd = NULL;
2027 shfl.wFunc = FO_DELETE;
2028 shfl.pFrom = path;
2029 shfl.pTo = NULL;
2030 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
2031
2032 SHFileOperation(&shfl);
2033
2034 lstrcpyA(path, PROG_FILES_DIR);
2035 lstrcatA(path, "\\msitest");
2036 RemoveDirectoryA(path);
2037 }
2038
2039 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
2040 {
2041 char val[MAX_PATH];
2042 DWORD size, type;
2043 LONG res;
2044
2045 size = MAX_PATH;
2046 val[0] = '\0';
2047 res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
2048
2049 if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
2050 {
2051 ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2052 return;
2053 }
2054
2055 if (!expected)
2056 ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
2057 else
2058 {
2059 if (bcase)
2060 ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
2061 else
2062 ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
2063 }
2064 }
2065
2066 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
2067 {
2068 DWORD val, size, type;
2069 LONG res;
2070
2071 size = sizeof(DWORD);
2072 res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2073
2074 if (res != ERROR_SUCCESS || type != REG_DWORD)
2075 {
2076 ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2077 return;
2078 }
2079
2080 ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
2081 }
2082
2083 #define CHECK_REG_STR(prodkey, name, expected) \
2084 check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2085
2086 #define CHECK_REG_ISTR(prodkey, name, expected) \
2087 check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2088
2089 #define CHECK_REG_DWORD(prodkey, name, expected) \
2090 check_reg_dword(prodkey, name, expected, __LINE__);
2091
2092 static void get_date_str(LPSTR date)
2093 {
2094 SYSTEMTIME systime;
2095
2096 static const char date_fmt[] = "%d%02d%02d";
2097 GetLocalTime(&systime);
2098 sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2099 }
2100
2101 static void test_publish_registerproduct(void)
2102 {
2103 UINT r;
2104 LONG res;
2105 HKEY uninstall, prodkey;
2106 INSTALLSTATE state;
2107 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2108 char date[MAX_PATH];
2109 char temp[MAX_PATH];
2110
2111 static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2112
2113 if (!pMsiQueryComponentStateA)
2114 {
2115 skip("MsiQueryComponentStateA is not available\n");
2116 return;
2117 }
2118
2119 get_date_str(date);
2120 GetTempPath(MAX_PATH, temp);
2121
2122 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2123 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2124
2125 CreateDirectoryA("msitest", NULL);
2126 create_file("msitest\\maximus", 500);
2127
2128 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2129
2130 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2131
2132 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2133 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2134
2135 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2136 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2137
2138 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2139 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2140
2141 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2142 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2143 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2144 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2145
2146 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2147 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2148
2149 /* RegisterProduct */
2150 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2152 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2153 ok(pf_exists("msitest"), "File not installed\n");
2154
2155 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2156 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2157
2158 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2159 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2160
2161 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2162 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2163
2164 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2165 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2166 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2167 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2168
2169 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2170 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2171
2172 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2173 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2174 CHECK_REG_STR(prodkey, "InstallDate", date);
2175 CHECK_REG_STR(prodkey, "InstallSource", temp);
2176 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2177 CHECK_REG_STR(prodkey, "Publisher", "Wine");
2178 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2179 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2180 CHECK_REG_STR(prodkey, "Comments", NULL);
2181 CHECK_REG_STR(prodkey, "Contact", NULL);
2182 CHECK_REG_STR(prodkey, "HelpLink", NULL);
2183 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2184 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2185 CHECK_REG_STR(prodkey, "Readme", NULL);
2186 CHECK_REG_STR(prodkey, "Size", NULL);
2187 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2188 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2189 CHECK_REG_DWORD(prodkey, "Language", 1033);
2190 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2191 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2192 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2193 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2194 todo_wine
2195 {
2196 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2197 }
2198
2199 RegCloseKey(prodkey);
2200
2201 /* try to uninstall after RegisterProduct */
2202 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2203 todo_wine
2204 {
2205 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2206 }
2207 ok(pf_exists("msitest\\maximus"), "File deleted\n");
2208 ok(pf_exists("msitest"), "File deleted\n");
2209
2210 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2211 todo_wine
2212 {
2213 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2214 }
2215
2216 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2217 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2218
2219 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2220 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2221
2222 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2223 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2224 todo_wine
2225 {
2226 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2227 }
2228 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2229
2230 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2231 todo_wine
2232 {
2233 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2234 }
2235
2236 todo_wine
2237 {
2238 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
2239 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
2240 CHECK_REG_STR(prodkey, "InstallDate", date);
2241 CHECK_REG_STR(prodkey, "InstallSource", temp);
2242 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2243 CHECK_REG_STR(prodkey, "Publisher", "Wine");
2244 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2245 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
2246 CHECK_REG_STR(prodkey, "Comments", NULL);
2247 CHECK_REG_STR(prodkey, "Contact", NULL);
2248 CHECK_REG_STR(prodkey, "HelpLink", NULL);
2249 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
2250 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
2251 CHECK_REG_STR(prodkey, "Readme", NULL);
2252 CHECK_REG_STR(prodkey, "Size", NULL);
2253 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
2254 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
2255 CHECK_REG_DWORD(prodkey, "Language", 1033);
2256 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
2257 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
2258 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
2259 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
2260 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
2261 }
2262
2263 RegCloseKey(prodkey);
2264
2265 /* full install to remove */
2266 r = MsiInstallProductA(msifile, "FULL=1");
2267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2268 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2269 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2270
2271 RegCloseKey(uninstall);
2272 DeleteFile(msifile);
2273 DeleteFile("msitest\\maximus");
2274 RemoveDirectory("msitest");
2275 delete_pfmsitest_files();
2276 }
2277
2278 static void test_publish_publishproduct(void)
2279 {
2280 UINT r;
2281 LONG res;
2282 HKEY uninstall, prodkey;
2283 INSTALLSTATE state;
2284 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2285
2286 static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2287
2288 if (!pMsiQueryComponentStateA)
2289 {
2290 skip("MsiQueryComponentStateA is not available\n");
2291 return;
2292 }
2293
2294 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2295 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2296
2297 CreateDirectoryA("msitest", NULL);
2298 create_file("msitest\\maximus", 500);
2299
2300 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2301
2302 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2303
2304 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2305 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2306
2307 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2308 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2309
2310 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2311 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2312
2313 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2314 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2315 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2316 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2317
2318 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2319 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2320
2321 /* PublishProduct */
2322 r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2324 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2325 ok(pf_exists("msitest"), "File not installed\n");
2326
2327 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2328 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2329
2330 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2331 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2332
2333 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2334 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2335
2336 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2337 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2338 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2339 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2340
2341 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2342 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2343
2344 /* try to uninstall after PublishProduct */
2345 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2347 ok(pf_exists("msitest\\maximus"), "File deleted\n");
2348 ok(pf_exists("msitest"), "File deleted\n");
2349
2350 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2351 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2352
2353 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2354 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2355
2356 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2357 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2358
2359 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2360 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2361 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2362 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2363
2364 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2365 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2366
2367 /* full install to remove */
2368 r = MsiInstallProductA(msifile, "FULL=1");
2369 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2370 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2372
2373 RegCloseKey(uninstall);
2374 DeleteFile(msifile);
2375 DeleteFile("msitest\\maximus");
2376 RemoveDirectory("msitest");
2377 delete_pfmsitest_files();
2378 }
2379
2380 static void test_publish_publishfeatures(void)
2381 {
2382 UINT r;
2383 LONG res;
2384 HKEY uninstall, prodkey;
2385 INSTALLSTATE state;
2386 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2387
2388 static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2389
2390 if (!pMsiQueryComponentStateA)
2391 {
2392 skip("MsiQueryComponentStateA is not available\n");
2393 return;
2394 }
2395
2396 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2397 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2398
2399 CreateDirectoryA("msitest", NULL);
2400 create_file("msitest\\maximus", 500);
2401
2402 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2403
2404 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2405
2406 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2407 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2408
2409 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2410 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2411
2412 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2413 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2414
2415 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2416 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2417 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2418 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2419
2420 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2421 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2422
2423 /* PublishFeatures */
2424 r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2426 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2427 ok(pf_exists("msitest"), "File not installed\n");
2428
2429 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2430 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2431
2432 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2433 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2434
2435 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2436 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2437
2438 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2439 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2440 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2441 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2442
2443 /* try to uninstall after PublishFeatures */
2444 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2445 todo_wine
2446 {
2447 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2448 }
2449 ok(pf_exists("msitest\\maximus"), "File deleted\n");
2450 ok(pf_exists("msitest"), "File deleted\n");
2451
2452 /* PublishFeatures and PublishProduct */
2453 r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 PUBLISH_FEATURES=1");
2454 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2455 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2456 ok(pf_exists("msitest"), "File not installed\n");
2457
2458 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2459 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2460
2461 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2462 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2463
2464 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2465 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2466
2467 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2468 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2469 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2470 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2471
2472 /* PublishFeatures and RegisterProduct */
2473 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_FEATURES=1");
2474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2475 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2476 ok(pf_exists("msitest"), "File not installed\n");
2477
2478 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2479 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2480
2481 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2482 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2483
2484 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2485 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2486
2487 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2488 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2489 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2490 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2491
2492 /* full install to remove */
2493 r = MsiInstallProductA(msifile, "FULL=1");
2494 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2495 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2497
2498 RegCloseKey(uninstall);
2499 DeleteFile(msifile);
2500 DeleteFile("msitest\\maximus");
2501 RemoveDirectory("msitest");
2502 delete_pfmsitest_files();
2503 }
2504
2505 static void test_publish_registeruser(void)
2506 {
2507 UINT r;
2508 LONG res;
2509 HKEY uninstall, prodkey;
2510 INSTALLSTATE state;
2511 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2512
2513 static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
2514
2515 if (!pMsiQueryComponentStateA)
2516 {
2517 skip("MsiQueryComponentStateA is not available\n");
2518 return;
2519 }
2520
2521 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
2522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2523
2524 CreateDirectoryA("msitest", NULL);
2525 create_file("msitest\\maximus", 500);
2526
2527 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2528
2529 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2530
2531 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2532 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2533
2534 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2535 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2536
2537 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2538 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2539
2540 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2541 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2542 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2543 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2544
2545 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2546 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2547
2548 /* RegisterUser */
2549 r = MsiInstallProductA(msifile, "REGISTER_USER=1");
2550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2551 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2552 ok(pf_exists("msitest"), "File not installed\n");
2553
2554 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2555 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2556
2557 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2558 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2559
2560 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2561 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2562
2563 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2564 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2565 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2566 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2567
2568 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2569 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2570
2571 /* try to uninstall after RegisterUser */
2572 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2573 todo_wine
2574 {
2575 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2576 }
2577 ok(pf_exists("msitest\\maximus"), "File deleted\n");
2578 ok(pf_exists("msitest"), "File deleted\n");
2579
2580 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2581 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2582
2583 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2584 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2585
2586 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2587 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2588
2589 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2590 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2591 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2592 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2593
2594 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
2595 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2596
2597 /* full install to remove */
2598 r = MsiInstallProductA(msifile, "FULL=1");
2599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2600 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2601 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2602
2603 RegCloseKey(uninstall);
2604 DeleteFile(msifile);
2605 DeleteFile("msitest\\maximus");
2606 RemoveDirectory("msitest");
2607 delete_pfmsitest_files();
2608 }
2609
2610 static void get_user_sid(LPSTR *usersid)
2611 {
2612 HANDLE token;
2613 BYTE buf[1024];
2614 DWORD size;
2615 PTOKEN_USER user;
2616 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
2617 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
2618
2619 *usersid = NULL;
2620 pConvertSidToStringSidA = (void *)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
2621 if (!pConvertSidToStringSidA)
2622 return;
2623
2624 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
2625 size = sizeof(buf);
2626 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);