Sync trunk head (r41026)
[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 static const CHAR is_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
634 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
635 "Feature\tFeature\n"
636 "one\t\t\t\t2\t1\t\t0\n" /* favorLocal */
637 "two\t\t\t\t2\t1\t\t1\n" /* favorSource */
638 "three\t\t\t\t2\t1\t\t4\n" /* favorAdvertise */
639 "four\t\t\t\t2\t0\t\t0"; /* disabled */
640
641 static const CHAR is_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
642 "s72\tS38\ts72\ti2\tS255\tS72\n"
643 "Component\tComponent\n"
644 "alpha\t\tMSITESTDIR\t0\t\talpha_file\n" /* favorLocal:Local */
645 "beta\t\tMSITESTDIR\t1\t\tbeta_file\n" /* favorLocal:Source */
646 "gamma\t\tMSITESTDIR\t2\t\tgamma_file\n" /* favorLocal:Optional */
647 "theta\t\tMSITESTDIR\t0\t\ttheta_file\n" /* favorSource:Local */
648 "delta\t\tMSITESTDIR\t1\t\tdelta_file\n" /* favorSource:Source */
649 "epsilon\t\tMSITESTDIR\t2\t\tepsilon_file\n" /* favorSource:Optional */
650 "zeta\t\tMSITESTDIR\t0\t\tzeta_file\n" /* favorAdvertise:Local */
651 "iota\t\tMSITESTDIR\t1\t\tiota_file\n" /* favorAdvertise:Source */
652 "eta\t\tMSITESTDIR\t2\t\teta_file\n" /* favorAdvertise:Optional */
653 "kappa\t\tMSITESTDIR\t0\t\tkappa_file\n" /* disabled:Local */
654 "lambda\t\tMSITESTDIR\t1\t\tlambda_file\n" /* disabled:Source */
655 "mu\t\tMSITESTDIR\t2\t\tmu_file\n"; /* disabled:Optional */
656
657 static const CHAR is_feature_comp_dat[] = "Feature_\tComponent_\n"
658 "s38\ts72\n"
659 "FeatureComponents\tFeature_\tComponent_\n"
660 "one\talpha\n"
661 "one\tbeta\n"
662 "one\tgamma\n"
663 "two\ttheta\n"
664 "two\tdelta\n"
665 "two\tepsilon\n"
666 "three\tzeta\n"
667 "three\tiota\n"
668 "three\teta\n"
669 "four\tkappa\n"
670 "four\tlambda\n"
671 "four\tmu";
672
673 static const CHAR is_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
674 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
675 "File\tFile\n"
676 "alpha_file\talpha\talpha\t500\t\t\t8192\t1\n"
677 "beta_file\tbeta\tbeta\t500\t\t\t8291\t2\n"
678 "gamma_file\tgamma\tgamma\t500\t\t\t8192\t3\n"
679 "theta_file\ttheta\ttheta\t500\t\t\t8192\t4\n"
680 "delta_file\tdelta\tdelta\t500\t\t\t8192\t5\n"
681 "epsilon_file\tepsilon\tepsilon\t500\t\t\t8192\t6\n"
682 "zeta_file\tzeta\tzeta\t500\t\t\t8192\t7\n"
683 "iota_file\tiota\tiota\t500\t\t\t8192\t8\n"
684 "eta_file\teta\teta\t500\t\t\t8192\t9\n"
685 "kappa_file\tkappa\tkappa\t500\t\t\t8192\t10\n"
686 "lambda_file\tlambda\tlambda\t500\t\t\t8192\t11\n"
687 "mu_file\tmu\tmu\t500\t\t\t8192\t12";
688
689 static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
690 "i2\ti4\tL64\tS255\tS32\tS72\n"
691 "Media\tDiskId\n"
692 "1\t12\t\t\tDISK1\t\n";
693
694 typedef struct _msi_table
695 {
696 const CHAR *filename;
697 const CHAR *data;
698 int size;
699 } msi_table;
700
701 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
702
703 static const msi_table tables[] =
704 {
705 ADD_TABLE(component),
706 ADD_TABLE(directory),
707 ADD_TABLE(feature),
708 ADD_TABLE(feature_comp),
709 ADD_TABLE(file),
710 ADD_TABLE(install_exec_seq),
711 ADD_TABLE(media),
712 ADD_TABLE(property),
713 ADD_TABLE(registry),
714 ADD_TABLE(service_install),
715 ADD_TABLE(service_control)
716 };
717
718 static const msi_table cc_tables[] =
719 {
720 ADD_TABLE(cc_component),
721 ADD_TABLE(directory),
722 ADD_TABLE(cc_feature),
723 ADD_TABLE(cc_feature_comp),
724 ADD_TABLE(cc_file),
725 ADD_TABLE(install_exec_seq),
726 ADD_TABLE(cc_media),
727 ADD_TABLE(property),
728 };
729
730 static const msi_table cc2_tables[] =
731 {
732 ADD_TABLE(cc2_component),
733 ADD_TABLE(directory),
734 ADD_TABLE(cc_feature),
735 ADD_TABLE(cc_feature_comp),
736 ADD_TABLE(cc2_file),
737 ADD_TABLE(install_exec_seq),
738 ADD_TABLE(cc_media),
739 ADD_TABLE(property),
740 };
741
742 static const msi_table co_tables[] =
743 {
744 ADD_TABLE(cc_component),
745 ADD_TABLE(directory),
746 ADD_TABLE(cc_feature),
747 ADD_TABLE(cc_feature_comp),
748 ADD_TABLE(co_file),
749 ADD_TABLE(install_exec_seq),
750 ADD_TABLE(co_media),
751 ADD_TABLE(property),
752 };
753
754 static const msi_table co2_tables[] =
755 {
756 ADD_TABLE(cc_component),
757 ADD_TABLE(directory),
758 ADD_TABLE(cc_feature),
759 ADD_TABLE(cc_feature_comp),
760 ADD_TABLE(cc_file),
761 ADD_TABLE(install_exec_seq),
762 ADD_TABLE(co2_media),
763 ADD_TABLE(property),
764 };
765
766 static const msi_table mm_tables[] =
767 {
768 ADD_TABLE(cc_component),
769 ADD_TABLE(directory),
770 ADD_TABLE(cc_feature),
771 ADD_TABLE(cc_feature_comp),
772 ADD_TABLE(mm_file),
773 ADD_TABLE(install_exec_seq),
774 ADD_TABLE(mm_media),
775 ADD_TABLE(property),
776 };
777
778 static const msi_table ss_tables[] =
779 {
780 ADD_TABLE(cc_component),
781 ADD_TABLE(directory),
782 ADD_TABLE(cc_feature),
783 ADD_TABLE(cc_feature_comp),
784 ADD_TABLE(cc_file),
785 ADD_TABLE(install_exec_seq),
786 ADD_TABLE(ss_media),
787 ADD_TABLE(property),
788 };
789
790 static const msi_table ui_tables[] =
791 {
792 ADD_TABLE(ui_component),
793 ADD_TABLE(directory),
794 ADD_TABLE(cc_feature),
795 ADD_TABLE(cc_feature_comp),
796 ADD_TABLE(cc_file),
797 ADD_TABLE(install_exec_seq),
798 ADD_TABLE(ui_install_ui_seq),
799 ADD_TABLE(ui_custom_action),
800 ADD_TABLE(cc_media),
801 ADD_TABLE(property),
802 };
803
804 static const msi_table rof_tables[] =
805 {
806 ADD_TABLE(rof_component),
807 ADD_TABLE(directory),
808 ADD_TABLE(rof_feature),
809 ADD_TABLE(rof_feature_comp),
810 ADD_TABLE(rof_file),
811 ADD_TABLE(install_exec_seq),
812 ADD_TABLE(rof_media),
813 ADD_TABLE(property),
814 };
815
816 static const msi_table sdp_tables[] =
817 {
818 ADD_TABLE(rof_component),
819 ADD_TABLE(directory),
820 ADD_TABLE(rof_feature),
821 ADD_TABLE(rof_feature_comp),
822 ADD_TABLE(rof_file),
823 ADD_TABLE(sdp_install_exec_seq),
824 ADD_TABLE(sdp_custom_action),
825 ADD_TABLE(rof_media),
826 ADD_TABLE(property),
827 };
828
829 static const msi_table cie_tables[] =
830 {
831 ADD_TABLE(cie_component),
832 ADD_TABLE(directory),
833 ADD_TABLE(cc_feature),
834 ADD_TABLE(cie_feature_comp),
835 ADD_TABLE(cie_file),
836 ADD_TABLE(install_exec_seq),
837 ADD_TABLE(cie_media),
838 ADD_TABLE(property),
839 };
840
841 static const msi_table ci_tables[] =
842 {
843 ADD_TABLE(ci_component),
844 ADD_TABLE(directory),
845 ADD_TABLE(rof_feature),
846 ADD_TABLE(rof_feature_comp),
847 ADD_TABLE(rof_file),
848 ADD_TABLE(ci_install_exec_seq),
849 ADD_TABLE(rof_media),
850 ADD_TABLE(property),
851 ADD_TABLE(ci_custom_action),
852 };
853
854 static const msi_table ci2_tables[] =
855 {
856 ADD_TABLE(ci2_component),
857 ADD_TABLE(directory),
858 ADD_TABLE(rof_feature),
859 ADD_TABLE(ci2_feature_comp),
860 ADD_TABLE(ci2_file),
861 ADD_TABLE(install_exec_seq),
862 ADD_TABLE(rof_media),
863 ADD_TABLE(property),
864 };
865
866 static const msi_table spf_tables[] =
867 {
868 ADD_TABLE(ci_component),
869 ADD_TABLE(directory),
870 ADD_TABLE(rof_feature),
871 ADD_TABLE(rof_feature_comp),
872 ADD_TABLE(rof_file),
873 ADD_TABLE(spf_install_exec_seq),
874 ADD_TABLE(rof_media),
875 ADD_TABLE(property),
876 ADD_TABLE(spf_custom_action),
877 ADD_TABLE(spf_install_ui_seq),
878 };
879
880 static const msi_table pp_tables[] =
881 {
882 ADD_TABLE(ci_component),
883 ADD_TABLE(directory),
884 ADD_TABLE(rof_feature),
885 ADD_TABLE(rof_feature_comp),
886 ADD_TABLE(rof_file),
887 ADD_TABLE(pp_install_exec_seq),
888 ADD_TABLE(rof_media),
889 ADD_TABLE(property),
890 };
891
892 static const msi_table tp_tables[] =
893 {
894 ADD_TABLE(tp_component),
895 ADD_TABLE(directory),
896 ADD_TABLE(rof_feature),
897 ADD_TABLE(ci2_feature_comp),
898 ADD_TABLE(ci2_file),
899 ADD_TABLE(install_exec_seq),
900 ADD_TABLE(rof_media),
901 ADD_TABLE(property),
902 };
903
904 static const msi_table cwd_tables[] =
905 {
906 ADD_TABLE(cwd_component),
907 ADD_TABLE(directory),
908 ADD_TABLE(rof_feature),
909 ADD_TABLE(ci2_feature_comp),
910 ADD_TABLE(ci2_file),
911 ADD_TABLE(install_exec_seq),
912 ADD_TABLE(rof_media),
913 ADD_TABLE(property),
914 };
915
916 static const msi_table adm_tables[] =
917 {
918 ADD_TABLE(adm_component),
919 ADD_TABLE(directory),
920 ADD_TABLE(rof_feature),
921 ADD_TABLE(ci2_feature_comp),
922 ADD_TABLE(ci2_file),
923 ADD_TABLE(install_exec_seq),
924 ADD_TABLE(rof_media),
925 ADD_TABLE(property),
926 ADD_TABLE(adm_custom_action),
927 ADD_TABLE(adm_admin_exec_seq),
928 };
929
930 static const msi_table amp_tables[] =
931 {
932 ADD_TABLE(amp_component),
933 ADD_TABLE(directory),
934 ADD_TABLE(rof_feature),
935 ADD_TABLE(ci2_feature_comp),
936 ADD_TABLE(ci2_file),
937 ADD_TABLE(install_exec_seq),
938 ADD_TABLE(rof_media),
939 ADD_TABLE(property),
940 };
941
942 static const msi_table rem_tables[] =
943 {
944 ADD_TABLE(rem_component),
945 ADD_TABLE(directory),
946 ADD_TABLE(rof_feature),
947 ADD_TABLE(rem_feature_comp),
948 ADD_TABLE(rem_file),
949 ADD_TABLE(rem_install_exec_seq),
950 ADD_TABLE(rof_media),
951 ADD_TABLE(property),
952 ADD_TABLE(rem_remove_files),
953 };
954
955 static const msi_table mov_tables[] =
956 {
957 ADD_TABLE(cwd_component),
958 ADD_TABLE(directory),
959 ADD_TABLE(rof_feature),
960 ADD_TABLE(ci2_feature_comp),
961 ADD_TABLE(ci2_file),
962 ADD_TABLE(install_exec_seq),
963 ADD_TABLE(rof_media),
964 ADD_TABLE(property),
965 ADD_TABLE(mov_move_file),
966 };
967
968 static const msi_table mc_tables[] =
969 {
970 ADD_TABLE(mc_component),
971 ADD_TABLE(directory),
972 ADD_TABLE(cc_feature),
973 ADD_TABLE(cie_feature_comp),
974 ADD_TABLE(mc_file),
975 ADD_TABLE(install_exec_seq),
976 ADD_TABLE(mc_media),
977 ADD_TABLE(property),
978 ADD_TABLE(mc_file_hash),
979 };
980
981 static const msi_table df_tables[] =
982 {
983 ADD_TABLE(rof_component),
984 ADD_TABLE(df_directory),
985 ADD_TABLE(rof_feature),
986 ADD_TABLE(rof_feature_comp),
987 ADD_TABLE(rof_file),
988 ADD_TABLE(install_exec_seq),
989 ADD_TABLE(rof_media),
990 ADD_TABLE(property),
991 ADD_TABLE(df_duplicate_file),
992 };
993
994 static const msi_table wrv_tables[] =
995 {
996 ADD_TABLE(wrv_component),
997 ADD_TABLE(directory),
998 ADD_TABLE(rof_feature),
999 ADD_TABLE(ci2_feature_comp),
1000 ADD_TABLE(ci2_file),
1001 ADD_TABLE(install_exec_seq),
1002 ADD_TABLE(rof_media),
1003 ADD_TABLE(property),
1004 ADD_TABLE(wrv_registry),
1005 };
1006
1007 static const msi_table sf_tables[] =
1008 {
1009 ADD_TABLE(wrv_component),
1010 ADD_TABLE(directory),
1011 ADD_TABLE(rof_feature),
1012 ADD_TABLE(ci2_feature_comp),
1013 ADD_TABLE(ci2_file),
1014 ADD_TABLE(install_exec_seq),
1015 ADD_TABLE(rof_media),
1016 ADD_TABLE(property),
1017 };
1018
1019 static const msi_table ca51_tables[] =
1020 {
1021 ADD_TABLE(ca51_component),
1022 ADD_TABLE(directory),
1023 ADD_TABLE(rof_feature),
1024 ADD_TABLE(ci2_feature_comp),
1025 ADD_TABLE(ci2_file),
1026 ADD_TABLE(ca51_install_exec_seq),
1027 ADD_TABLE(rof_media),
1028 ADD_TABLE(property),
1029 ADD_TABLE(ca51_custom_action),
1030 };
1031
1032 static const msi_table is_tables[] =
1033 {
1034 ADD_TABLE(is_component),
1035 ADD_TABLE(directory),
1036 ADD_TABLE(is_feature),
1037 ADD_TABLE(is_feature_comp),
1038 ADD_TABLE(is_file),
1039 ADD_TABLE(install_exec_seq),
1040 ADD_TABLE(is_media),
1041 ADD_TABLE(property),
1042 };
1043
1044 /* cabinet definitions */
1045
1046 /* make the max size large so there is only one cab file */
1047 #define MEDIA_SIZE 0x7FFFFFFF
1048 #define FOLDER_THRESHOLD 900000
1049
1050 /* the FCI callbacks */
1051
1052 static void *mem_alloc(ULONG cb)
1053 {
1054 return HeapAlloc(GetProcessHeap(), 0, cb);
1055 }
1056
1057 static void mem_free(void *memory)
1058 {
1059 HeapFree(GetProcessHeap(), 0, memory);
1060 }
1061
1062 static BOOL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
1063 {
1064 sprintf(pccab->szCab, pv, pccab->iCab);
1065 return TRUE;
1066 }
1067
1068 static long progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
1069 {
1070 return 0;
1071 }
1072
1073 static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
1074 BOOL fContinuation, void *pv)
1075 {
1076 return 0;
1077 }
1078
1079 static INT_PTR fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
1080 {
1081 HANDLE handle;
1082 DWORD dwAccess = 0;
1083 DWORD dwShareMode = 0;
1084 DWORD dwCreateDisposition = OPEN_EXISTING;
1085
1086 dwAccess = GENERIC_READ | GENERIC_WRITE;
1087 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
1088 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1089
1090 if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
1091 dwCreateDisposition = OPEN_EXISTING;
1092 else
1093 dwCreateDisposition = CREATE_NEW;
1094
1095 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
1096 dwCreateDisposition, 0, NULL);
1097
1098 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
1099
1100 return (INT_PTR)handle;
1101 }
1102
1103 static UINT fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1104 {
1105 HANDLE handle = (HANDLE)hf;
1106 DWORD dwRead;
1107 BOOL res;
1108
1109 res = ReadFile(handle, memory, cb, &dwRead, NULL);
1110 ok(res, "Failed to ReadFile\n");
1111
1112 return dwRead;
1113 }
1114
1115 static UINT fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
1116 {
1117 HANDLE handle = (HANDLE)hf;
1118 DWORD dwWritten;
1119 BOOL res;
1120
1121 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
1122 ok(res, "Failed to WriteFile\n");
1123
1124 return dwWritten;
1125 }
1126
1127 static int fci_close(INT_PTR hf, int *err, void *pv)
1128 {
1129 HANDLE handle = (HANDLE)hf;
1130 ok(CloseHandle(handle), "Failed to CloseHandle\n");
1131
1132 return 0;
1133 }
1134
1135 static long fci_seek(INT_PTR hf, long dist, int seektype, int *err, void *pv)
1136 {
1137 HANDLE handle = (HANDLE)hf;
1138 DWORD ret;
1139
1140 ret = SetFilePointer(handle, dist, NULL, seektype);
1141 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
1142
1143 return ret;
1144 }
1145
1146 static int fci_delete(char *pszFile, int *err, void *pv)
1147 {
1148 BOOL ret = DeleteFileA(pszFile);
1149 ok(ret, "Failed to DeleteFile %s\n", pszFile);
1150
1151 return 0;
1152 }
1153
1154 static void init_functionpointers(void)
1155 {
1156 HMODULE hmsi = GetModuleHandleA("msi.dll");
1157
1158 #define GET_PROC(func) \
1159 p ## func = (void*)GetProcAddress(hmsi, #func); \
1160 if(!p ## func) \
1161 trace("GetProcAddress(%s) failed\n", #func);
1162
1163 GET_PROC(MsiQueryComponentStateA);
1164 GET_PROC(MsiSourceListEnumSourcesA);
1165 GET_PROC(MsiSourceListGetInfoA);
1166
1167 #undef GET_PROC
1168 }
1169
1170 static void get_user_sid(LPSTR *usersid)
1171 {
1172 HANDLE token;
1173 BYTE buf[1024];
1174 DWORD size;
1175 PTOKEN_USER user;
1176 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
1177 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
1178
1179 *usersid = NULL;
1180 pConvertSidToStringSidA = (void *)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
1181 if (!pConvertSidToStringSidA)
1182 return;
1183
1184 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1185 size = sizeof(buf);
1186 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
1187 user = (PTOKEN_USER)buf;
1188 pConvertSidToStringSidA(user->User.Sid, usersid);
1189 }
1190
1191 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
1192 {
1193 CHAR buffer[0x20];
1194 UINT r;
1195 DWORD sz;
1196
1197 sz = sizeof buffer;
1198 r = MsiRecordGetString(rec, field, buffer, &sz);
1199 return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
1200 }
1201
1202 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
1203 {
1204 LPSTR tempname;
1205
1206 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
1207 GetTempFileNameA(".", "xx", 0, tempname);
1208
1209 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
1210 {
1211 lstrcpyA(pszTempName, tempname);
1212 HeapFree(GetProcessHeap(), 0, tempname);
1213 return TRUE;
1214 }
1215
1216 HeapFree(GetProcessHeap(), 0, tempname);
1217
1218 return FALSE;
1219 }
1220
1221 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
1222 USHORT *pattribs, int *err, void *pv)
1223 {
1224 BY_HANDLE_FILE_INFORMATION finfo;
1225 FILETIME filetime;
1226 HANDLE handle;
1227 DWORD attrs;
1228 BOOL res;
1229
1230 handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
1231 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1232
1233 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
1234
1235 res = GetFileInformationByHandle(handle, &finfo);
1236 ok(res, "Expected GetFileInformationByHandle to succeed\n");
1237
1238 FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
1239 FileTimeToDosDateTime(&filetime, pdate, ptime);
1240
1241 attrs = GetFileAttributes(pszName);
1242 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
1243
1244 return (INT_PTR)handle;
1245 }
1246
1247 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
1248 {
1249 char path[MAX_PATH];
1250 char filename[MAX_PATH];
1251
1252 lstrcpyA(path, CURR_DIR);
1253 lstrcatA(path, "\\");
1254 lstrcatA(path, file);
1255
1256 lstrcpyA(filename, file);
1257
1258 return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
1259 progress, get_open_info, compress);
1260 }
1261
1262 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
1263 {
1264 ZeroMemory(pCabParams, sizeof(CCAB));
1265
1266 pCabParams->cb = max_size;
1267 pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
1268 pCabParams->setID = 0xbeef;
1269 pCabParams->iCab = 1;
1270 lstrcpyA(pCabParams->szCabPath, CURR_DIR);
1271 lstrcatA(pCabParams->szCabPath, "\\");
1272 lstrcpyA(pCabParams->szCab, name);
1273 }
1274
1275 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
1276 {
1277 CCAB cabParams;
1278 LPCSTR ptr;
1279 HFCI hfci;
1280 ERF erf;
1281 BOOL res;
1282
1283 set_cab_parameters(&cabParams, name, max_size);
1284
1285 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1286 fci_read, fci_write, fci_close, fci_seek, fci_delete,
1287 get_temp_file, &cabParams, NULL);
1288
1289 ok(hfci != NULL, "Failed to create an FCI context\n");
1290
1291 ptr = files;
1292 while (*ptr)
1293 {
1294 res = add_file(hfci, ptr, tcompTYPE_MSZIP);
1295 ok(res, "Failed to add file: %s\n", ptr);
1296 ptr += lstrlen(ptr) + 1;
1297 }
1298
1299 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1300 ok(res, "Failed to flush the cabinet\n");
1301
1302 res = FCIDestroy(hfci);
1303 ok(res, "Failed to destroy the cabinet\n");
1304 }
1305
1306 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1307 {
1308 HKEY hkey;
1309 DWORD type, size;
1310
1311 if (RegOpenKey(HKEY_LOCAL_MACHINE,
1312 "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1313 return FALSE;
1314
1315 size = MAX_PATH;
1316 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1317 RegCloseKey(hkey);
1318 return FALSE;
1319 }
1320
1321 size = MAX_PATH;
1322 if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1323 RegCloseKey(hkey);
1324 return FALSE;
1325 }
1326
1327 RegCloseKey(hkey);
1328 return TRUE;
1329 }
1330
1331 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
1332 {
1333 HANDLE file;
1334 DWORD written;
1335
1336 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1337 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1338 WriteFile(file, data, strlen(data), &written, NULL);
1339
1340 if (size)
1341 {
1342 SetFilePointer(file, size, NULL, FILE_BEGIN);
1343 SetEndOfFile(file);
1344 }
1345
1346 CloseHandle(file);
1347 }
1348
1349 #define create_file(name, size) create_file_data(name, name, size)
1350
1351 static void create_test_files(void)
1352 {
1353 CreateDirectoryA("msitest", NULL);
1354 create_file("msitest\\one.txt", 100);
1355 CreateDirectoryA("msitest\\first", NULL);
1356 create_file("msitest\\first\\two.txt", 100);
1357 CreateDirectoryA("msitest\\second", NULL);
1358 create_file("msitest\\second\\three.txt", 100);
1359
1360 create_file("four.txt", 100);
1361 create_file("five.txt", 100);
1362 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1363
1364 create_file("msitest\\filename", 100);
1365 create_file("msitest\\service.exe", 100);
1366
1367 DeleteFileA("four.txt");
1368 DeleteFileA("five.txt");
1369 }
1370
1371 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1372 {
1373 CHAR path[MAX_PATH];
1374
1375 lstrcpyA(path, PROG_FILES_DIR);
1376 lstrcatA(path, "\\");
1377 lstrcatA(path, rel_path);
1378
1379 if (is_file)
1380 return DeleteFileA(path);
1381 else
1382 return RemoveDirectoryA(path);
1383 }
1384
1385 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1386 {
1387 CHAR path[MAX_PATH];
1388
1389 lstrcpyA(path, COMMON_FILES_DIR);
1390 lstrcatA(path, "\\");
1391 lstrcatA(path, rel_path);
1392
1393 if (is_file)
1394 return DeleteFileA(path);
1395 else
1396 return RemoveDirectoryA(path);
1397 }
1398
1399 static void delete_test_files(void)
1400 {
1401 DeleteFileA("msitest.msi");
1402 DeleteFileA("msitest.cab");
1403 DeleteFileA("msitest\\second\\three.txt");
1404 DeleteFileA("msitest\\first\\two.txt");
1405 DeleteFileA("msitest\\one.txt");
1406 DeleteFileA("msitest\\service.exe");
1407 DeleteFileA("msitest\\filename");
1408 RemoveDirectoryA("msitest\\second");
1409 RemoveDirectoryA("msitest\\first");
1410 RemoveDirectoryA("msitest");
1411 }
1412
1413 static void write_file(const CHAR *filename, const char *data, int data_size)
1414 {
1415 DWORD size;
1416
1417 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1418 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1419
1420 WriteFile(hf, data, data_size, &size, NULL);
1421 CloseHandle(hf);
1422 }
1423
1424 static void write_msi_summary_info(MSIHANDLE db)
1425 {
1426 MSIHANDLE summary;
1427 UINT r;
1428
1429 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1430 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1431
1432 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1434
1435 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1436 "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1438
1439 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1441
1442 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1444
1445 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1446 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1447
1448 /* write the summary changes back to the stream */
1449 r = MsiSummaryInfoPersist(summary);
1450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1451
1452 MsiCloseHandle(summary);
1453 }
1454
1455 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1456 {
1457 MSIHANDLE db;
1458 UINT r;
1459 int j;
1460
1461 r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1463
1464 /* import the tables into the database */
1465 for (j = 0; j < num_tables; j++)
1466 {
1467 const msi_table *table = &tables[j];
1468
1469 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1470
1471 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1473
1474 DeleteFileA(table->filename);
1475 }
1476
1477 write_msi_summary_info(db);
1478
1479 r = MsiDatabaseCommit(db);
1480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1481
1482 MsiCloseHandle(db);
1483 }
1484
1485 static void check_service_is_installed(void)
1486 {
1487 SC_HANDLE scm, service;
1488 BOOL res;
1489
1490 scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1491 ok(scm != NULL, "Failed to open the SC Manager\n");
1492
1493 service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1494 ok(service != NULL, "Failed to open TestService\n");
1495
1496 res = DeleteService(service);
1497 ok(res, "Failed to delete TestService\n");
1498
1499 CloseServiceHandle(service);
1500 CloseServiceHandle(scm);
1501 }
1502
1503 static void test_MsiInstallProduct(void)
1504 {
1505 UINT r;
1506 CHAR path[MAX_PATH];
1507 LONG res;
1508 HKEY hkey;
1509 DWORD num, size, type;
1510 SC_HANDLE scm;
1511
1512 scm = OpenSCManager(NULL, NULL, GENERIC_ALL);
1513 if (!scm && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1514 {
1515 skip("Services are not implemented, we are most likely on win9x\n");
1516 return;
1517 }
1518 CloseServiceHandle(scm);
1519
1520 create_test_files();
1521 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1522
1523 r = MsiInstallProductA(msifile, NULL);
1524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1525
1526 ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1527 ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1528 ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1529 ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1530 ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1531 ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1532 ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1533 ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1534 ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1535 ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1536 ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1537 ok(delete_pf("msitest", FALSE), "File not installed\n");
1538
1539 res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1540 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1541
1542 size = MAX_PATH;
1543 type = REG_SZ;
1544 res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1545 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1546 ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1547
1548 size = MAX_PATH;
1549 type = REG_SZ;
1550 res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1551 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1552
1553 size = sizeof(num);
1554 type = REG_DWORD;
1555 res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1557 ok(num == 314, "Expected 314, got %d\n", num);
1558
1559 size = MAX_PATH;
1560 type = REG_SZ;
1561 res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1563 ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1564
1565 check_service_is_installed();
1566
1567 RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1568
1569 delete_test_files();
1570 }
1571
1572 static void test_MsiSetComponentState(void)
1573 {
1574 INSTALLSTATE installed, action;
1575 MSIHANDLE package;
1576 char path[MAX_PATH];
1577 UINT r;
1578
1579 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1580
1581 CoInitialize(NULL);
1582
1583 lstrcpy(path, CURR_DIR);
1584 lstrcat(path, "\\");
1585 lstrcat(path, msifile);
1586
1587 r = MsiOpenPackage(path, &package);
1588 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1589
1590 r = MsiDoAction(package, "CostInitialize");
1591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1592
1593 r = MsiDoAction(package, "FileCost");
1594 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1595
1596 r = MsiDoAction(package, "CostFinalize");
1597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1598
1599 r = MsiGetComponentState(package, "dangler", &installed, &action);
1600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1601 ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1602 ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1603
1604 r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1605 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1606
1607 MsiCloseHandle(package);
1608 CoUninitialize();
1609
1610 DeleteFileA(msifile);
1611 }
1612
1613 static void test_packagecoltypes(void)
1614 {
1615 MSIHANDLE hdb, view, rec;
1616 char path[MAX_PATH];
1617 LPCSTR query;
1618 UINT r, count;
1619
1620 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1621
1622 CoInitialize(NULL);
1623
1624 lstrcpy(path, CURR_DIR);
1625 lstrcat(path, "\\");
1626 lstrcat(path, msifile);
1627
1628 r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1630
1631 query = "SELECT * FROM `Media`";
1632 r = MsiDatabaseOpenView( hdb, query, &view );
1633 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1634
1635 r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1636 count = MsiRecordGetFieldCount( rec );
1637 ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1638 ok(count == 6, "Expected 6, got %d\n", count);
1639 ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1640 ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1641 ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1642 ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1643 ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1644 ok(check_record(rec, 6, "Source"), "wrong column label\n");
1645 MsiCloseHandle(rec);
1646
1647 r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1648 count = MsiRecordGetFieldCount( rec );
1649 ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1650 ok(count == 6, "Expected 6, got %d\n", count);
1651 ok(check_record(rec, 1, "i2"), "wrong column label\n");
1652 ok(check_record(rec, 2, "i4"), "wrong column label\n");
1653 ok(check_record(rec, 3, "L64"), "wrong column label\n");
1654 ok(check_record(rec, 4, "S255"), "wrong column label\n");
1655 ok(check_record(rec, 5, "S32"), "wrong column label\n");
1656 ok(check_record(rec, 6, "S72"), "wrong column label\n");
1657
1658 MsiCloseHandle(rec);
1659 MsiCloseHandle(view);
1660 MsiCloseHandle(hdb);
1661 DeleteFile(msifile);
1662 }
1663
1664 static void create_cc_test_files(void)
1665 {
1666 CCAB cabParams;
1667 HFCI hfci;
1668 ERF erf;
1669 static CHAR cab_context[] = "test%d.cab";
1670 BOOL res;
1671
1672 create_file("maximus", 500);
1673 create_file("augustus", 50000);
1674 create_file("tiberius", 500);
1675 create_file("caesar", 500);
1676
1677 set_cab_parameters(&cabParams, "test1.cab", 40000);
1678
1679 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1680 fci_read, fci_write, fci_close, fci_seek, fci_delete,
1681 get_temp_file, &cabParams, cab_context);
1682 ok(hfci != NULL, "Failed to create an FCI context\n");
1683
1684 res = add_file(hfci, "maximus", tcompTYPE_NONE);
1685 ok(res, "Failed to add file maximus\n");
1686
1687 res = add_file(hfci, "augustus", tcompTYPE_NONE);
1688 ok(res, "Failed to add file augustus\n");
1689
1690 res = add_file(hfci, "tiberius", tcompTYPE_NONE);
1691 ok(res, "Failed to add file tiberius\n");
1692
1693 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1694 ok(res, "Failed to flush the cabinet\n");
1695
1696 res = FCIDestroy(hfci);
1697 ok(res, "Failed to destroy the cabinet\n");
1698
1699 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1700
1701 DeleteFile("maximus");
1702 DeleteFile("augustus");
1703 DeleteFile("tiberius");
1704 DeleteFile("caesar");
1705 }
1706
1707 static void delete_cab_files(void)
1708 {
1709 SHFILEOPSTRUCT shfl;
1710 CHAR path[MAX_PATH+10];
1711
1712 lstrcpyA(path, CURR_DIR);
1713 lstrcatA(path, "\\*.cab");
1714 path[strlen(path) + 1] = '\0';
1715
1716 shfl.hwnd = NULL;
1717 shfl.wFunc = FO_DELETE;
1718 shfl.pFrom = path;
1719 shfl.pTo = NULL;
1720 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1721
1722 SHFileOperation(&shfl);
1723 }
1724
1725 static void test_continuouscabs(void)
1726 {
1727 UINT r;
1728
1729 create_cc_test_files();
1730 create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1731
1732 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1733
1734 r = MsiInstallProductA(msifile, NULL);
1735 if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1736 {
1737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1738 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1739 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1740 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1741 ok(delete_pf("msitest", FALSE), "File not installed\n");
1742 }
1743
1744 delete_cab_files();
1745 DeleteFile(msifile);
1746
1747 create_cc_test_files();
1748 create_database(msifile, cc2_tables, sizeof(cc2_tables) / sizeof(msi_table));
1749
1750 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1751
1752 r = MsiInstallProductA(msifile, NULL);
1753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1754 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1755 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
1756 ok(delete_pf("msitest\\tiberius", TRUE), "File not installed\n");
1757 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1758 ok(delete_pf("msitest", FALSE), "File not installed\n");
1759
1760 delete_cab_files();
1761 DeleteFile(msifile);
1762 }
1763
1764 static void test_caborder(void)
1765 {
1766 UINT r;
1767
1768 create_file("imperator", 100);
1769 create_file("maximus", 500);
1770 create_file("augustus", 50000);
1771 create_file("caesar", 500);
1772
1773 create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1774
1775 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1776
1777 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1778 create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1779 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1780
1781 r = MsiInstallProductA(msifile, NULL);
1782 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1783 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1784 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1785 todo_wine
1786 {
1787 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1788 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1789 }
1790
1791 delete_cab_files();
1792
1793 create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1794 create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1795 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1796
1797 r = MsiInstallProductA(msifile, NULL);
1798 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1799 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1800 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1801 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1802 todo_wine
1803 {
1804 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1805 }
1806
1807 delete_cab_files();
1808 DeleteFile(msifile);
1809
1810 create_cc_test_files();
1811 create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1812
1813 r = MsiInstallProductA(msifile, NULL);
1814 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1815 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1816 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1817 todo_wine
1818 {
1819 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1820 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1821 }
1822
1823 delete_cab_files();
1824 DeleteFile(msifile);
1825
1826 create_cc_test_files();
1827 create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1828
1829 r = MsiInstallProductA(msifile, NULL);
1830 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1831 todo_wine
1832 {
1833 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1834 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1835 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1836 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1837 }
1838
1839 delete_cab_files();
1840 DeleteFile("imperator");
1841 DeleteFile("maximus");
1842 DeleteFile("augustus");
1843 DeleteFile("caesar");
1844 DeleteFile(msifile);
1845 }
1846
1847 static void test_mixedmedia(void)
1848 {
1849 UINT r;
1850
1851 CreateDirectoryA("msitest", NULL);
1852 create_file("msitest\\maximus", 500);
1853 create_file("msitest\\augustus", 500);
1854 create_file("caesar", 500);
1855
1856 create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1857
1858 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1859
1860 create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1861
1862 r = MsiInstallProductA(msifile, NULL);
1863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1864 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1865 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1866 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1867 ok(delete_pf("msitest", FALSE), "File not installed\n");
1868
1869 /* Delete the files in the temp (current) folder */
1870 DeleteFile("msitest\\maximus");
1871 DeleteFile("msitest\\augustus");
1872 RemoveDirectory("msitest");
1873 DeleteFile("caesar");
1874 DeleteFile("test1.cab");
1875 DeleteFile(msifile);
1876 }
1877
1878 static void test_samesequence(void)
1879 {
1880 UINT r;
1881
1882 create_cc_test_files();
1883 create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1884
1885 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1886
1887 r = MsiInstallProductA(msifile, NULL);
1888 if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1889 {
1890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1891 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1892 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1893 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1894 ok(delete_pf("msitest", FALSE), "File not installed\n");
1895 }
1896
1897 delete_cab_files();
1898 DeleteFile(msifile);
1899 }
1900
1901 static void test_uiLevelFlags(void)
1902 {
1903 UINT r;
1904
1905 create_cc_test_files();
1906 create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1907
1908 MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1909
1910 r = MsiInstallProductA(msifile, NULL);
1911 if (r == ERROR_SUCCESS) /* win9x has a problem with this */
1912 {
1913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1914 ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1915 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1916 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1917 ok(delete_pf("msitest", FALSE), "File not installed\n");
1918 }
1919
1920 delete_cab_files();
1921 DeleteFile(msifile);
1922 }
1923
1924 static BOOL file_matches(LPSTR path)
1925 {
1926 CHAR buf[MAX_PATH];
1927 HANDLE file;
1928 DWORD size;
1929
1930 file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1931 NULL, OPEN_EXISTING, 0, NULL);
1932
1933 ZeroMemory(buf, MAX_PATH);
1934 ReadFile(file, buf, 15, &size, NULL);
1935 CloseHandle(file);
1936
1937 return !lstrcmp(buf, "msitest\\maximus");
1938 }
1939
1940 static void test_readonlyfile(void)
1941 {
1942 UINT r;
1943 DWORD size;
1944 HANDLE file;
1945 CHAR path[MAX_PATH];
1946
1947 CreateDirectoryA("msitest", NULL);
1948 create_file("msitest\\maximus", 500);
1949 create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1950
1951 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1952
1953 lstrcpy(path, PROG_FILES_DIR);
1954 lstrcat(path, "\\msitest");
1955 CreateDirectory(path, NULL);
1956
1957 lstrcat(path, "\\maximus");
1958 file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1959 NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1960
1961 WriteFile(file, "readonlyfile", 20, &size, NULL);
1962 CloseHandle(file);
1963
1964 r = MsiInstallProductA(msifile, NULL);
1965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1966 ok(file_matches(path), "Expected file to be overwritten\n");
1967 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1968 ok(delete_pf("msitest", FALSE), "File not installed\n");
1969
1970 /* Delete the files in the temp (current) folder */
1971 DeleteFile("msitest\\maximus");
1972 RemoveDirectory("msitest");
1973 DeleteFile(msifile);
1974 }
1975
1976 static void test_setdirproperty(void)
1977 {
1978 UINT r;
1979
1980 CreateDirectoryA("msitest", NULL);
1981 create_file("msitest\\maximus", 500);
1982 create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1983
1984 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1985
1986 r = MsiInstallProductA(msifile, NULL);
1987 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1988 ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1989 ok(delete_cf("msitest", FALSE), "File not installed\n");
1990
1991 /* Delete the files in the temp (current) folder */
1992 DeleteFile(msifile);
1993 DeleteFile("msitest\\maximus");
1994 RemoveDirectory("msitest");
1995 }
1996
1997 static void test_cabisextracted(void)
1998 {
1999 UINT r;
2000
2001 CreateDirectoryA("msitest", NULL);
2002 create_file("msitest\\gaius", 500);
2003 create_file("maximus", 500);
2004 create_file("augustus", 500);
2005 create_file("caesar", 500);
2006
2007 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
2008 create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
2009 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
2010
2011 create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
2012
2013 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2014
2015 r = MsiInstallProductA(msifile, NULL);
2016 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2017 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2018 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2019 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
2020 ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
2021 ok(delete_pf("msitest", FALSE), "File not installed\n");
2022
2023 /* Delete the files in the temp (current) folder */
2024 delete_cab_files();
2025 DeleteFile(msifile);
2026 DeleteFile("maximus");
2027 DeleteFile("augustus");
2028 DeleteFile("caesar");
2029 DeleteFile("msitest\\gaius");
2030 RemoveDirectory("msitest");
2031 }
2032
2033 static void test_concurrentinstall(void)
2034 {
2035 UINT r;
2036 CHAR path[MAX_PATH];
2037
2038 CreateDirectoryA("msitest", NULL);
2039 CreateDirectoryA("msitest\\msitest", NULL);
2040 create_file("msitest\\maximus", 500);
2041 create_file("msitest\\msitest\\augustus", 500);
2042
2043 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
2044
2045 lstrcpyA(path, CURR_DIR);
2046 lstrcatA(path, "\\msitest\\concurrent.msi");
2047 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
2048
2049 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2050
2051 r = MsiInstallProductA(msifile, NULL);
2052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2053 if (!delete_pf("msitest\\augustus", TRUE))
2054 trace("concurrent installs not supported\n");
2055 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2056 ok(delete_pf("msitest", FALSE), "File not installed\n");
2057
2058 DeleteFile(path);
2059
2060 r = MsiInstallProductA(msifile, NULL);
2061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2062 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2063 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2064 ok(delete_pf("msitest", FALSE), "File not installed\n");
2065
2066 DeleteFile(msifile);
2067 DeleteFile("msitest\\msitest\\augustus");
2068 DeleteFile("msitest\\maximus");
2069 RemoveDirectory("msitest\\msitest");
2070 RemoveDirectory("msitest");
2071 }
2072
2073 static void test_setpropertyfolder(void)
2074 {
2075 UINT r;
2076 CHAR path[MAX_PATH];
2077
2078 lstrcpyA(path, PROG_FILES_DIR);
2079 lstrcatA(path, "\\msitest\\added");
2080
2081 CreateDirectoryA("msitest", NULL);
2082 create_file("msitest\\maximus", 500);
2083
2084 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
2085
2086 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2087
2088 r = MsiInstallProductA(msifile, NULL);
2089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2090 if (GetFileAttributesA(path) == FILE_ATTRIBUTE_DIRECTORY)
2091 {
2092 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
2093 ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
2094 ok(delete_pf("msitest", FALSE), "File not installed\n");
2095 }
2096 else
2097 {
2098 trace("changing folder property not supported\n");
2099 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2100 ok(delete_pf("msitest", FALSE), "File not installed\n");
2101 }
2102
2103 /* Delete the files in the temp (current) folder */
2104 DeleteFile(msifile);
2105 DeleteFile("msitest\\maximus");
2106 RemoveDirectory("msitest");
2107 }
2108
2109 static BOOL file_exists(LPCSTR file)
2110 {
2111 return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
2112 }
2113
2114 static BOOL pf_exists(LPCSTR file)
2115 {
2116 CHAR path[MAX_PATH];
2117
2118 lstrcpyA(path, PROG_FILES_DIR);
2119 lstrcatA(path, "\\");
2120 lstrcatA(path, file);
2121
2122 return file_exists(path);
2123 }
2124
2125 static void delete_pfmsitest_files(void)
2126 {
2127 SHFILEOPSTRUCT shfl;
2128 CHAR path[MAX_PATH+11];
2129
2130 lstrcpyA(path, PROG_FILES_DIR);
2131 lstrcatA(path, "\\msitest\\*");
2132 path[strlen(path) + 1] = '\0';
2133
2134 shfl.hwnd = NULL;
2135 shfl.wFunc = FO_DELETE;
2136 shfl.pFrom = path;
2137 shfl.pTo = NULL;
2138 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
2139
2140 SHFileOperation(&shfl);
2141
2142 lstrcpyA(path, PROG_FILES_DIR);
2143 lstrcatA(path, "\\msitest");
2144 RemoveDirectoryA(path);
2145 }
2146
2147 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
2148 {
2149 char val[MAX_PATH];
2150 DWORD size, type;
2151 LONG res;
2152
2153 size = MAX_PATH;
2154 val[0] = '\0';
2155 res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
2156
2157 if (res != ERROR_SUCCESS ||
2158 (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
2159 {
2160 ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2161 return;
2162 }
2163
2164 if (!expected)
2165 ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
2166 else
2167 {
2168 if (bcase)
2169 ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
2170 else
2171 ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
2172 }
2173 }
2174
2175 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
2176 {
2177 DWORD val, size, type;
2178 LONG res;
2179
2180 size = sizeof(DWORD);
2181 res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2182
2183 if (res != ERROR_SUCCESS || type != REG_DWORD)
2184 {
2185 ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2186 return;
2187 }
2188
2189 ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
2190 }
2191
2192 #define CHECK_REG_STR(prodkey, name, expected) \
2193 check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2194
2195 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
2196 check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
2197 RegDeleteValueA(prodkey, name);
2198
2199 #define CHECK_REG_ISTR(prodkey, name, expected) \
2200 check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2201
2202 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
2203 check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
2204 RegDeleteValueA(prodkey, name);
2205
2206 #define CHECK_REG_DWORD(prodkey, name, expected) \
2207 check_reg_dword(prodkey, name, expected, __LINE__);
2208
2209 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
2210 check_reg_dword(prodkey, name, expected, __LINE__); \
2211 RegDeleteValueA(prodkey, name);
2212
2213 static void get_date_str(LPSTR date)
2214 {
2215 SYSTEMTIME systime;
2216
2217 static const char date_fmt[] = "%d%02d%02d";
2218 GetLocalTime(&systime);
2219 sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2220 }
2221
2222 static void test_publish_registerproduct(void)
2223 {
2224 UINT r;
2225 LONG res;
2226 HKEY hkey;
2227 HKEY props, usage;
2228 LPSTR usersid;
2229 char date[MAX_PATH];
2230 char temp[MAX_PATH];
2231 char keypath[MAX_PATH];
2232
2233 static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2234 "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2235 static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2236 "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2237 static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2238 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2239 static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2240 "\\51AAE0C44620A5E4788506E91F249BD2";
2241
2242 get_user_sid(&usersid);
2243 if (!usersid)
2244 {
2245 skip("ConvertSidToStringSidA is not available\n");
2246 return;
2247 }
2248
2249 get_date_str(date);
2250 GetTempPath(MAX_PATH, temp);
2251
2252 CreateDirectoryA("msitest", NULL);
2253 create_file("msitest\\maximus", 500);
2254
2255 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2256
2257 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2258
2259 /* RegisterProduct */
2260 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2262 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2263 ok(delete_pf("msitest", FALSE), "File not installed\n");
2264
2265 res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
2266 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2267
2268 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
2269 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2270
2271 CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2272 CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2273 CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2274 CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2275 CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2276 CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2277 CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2278 CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2279 CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2280 CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2281 CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2282 CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2283 CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2284 CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2285 CHECK_DEL_REG_STR(hkey, "Size", NULL);
2286 CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2287 CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2288 CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2289 CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2290 CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2291 CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2292 CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2293 todo_wine
2294 {
2295 CHECK_DEL_REG_DWORD(hkey, "EstimatedSize", 12);
2296 }
2297
2298 RegDeleteKeyA(hkey, "");
2299 RegCloseKey(hkey);
2300
2301 sprintf(keypath, userdata, usersid);
2302 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2303 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2304
2305 res = RegOpenKeyA(hkey, "InstallProperties", &props);
2306 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2307
2308 RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2309 CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2310 CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2311 CHECK_DEL_REG_STR(props, "InstallDate", date);
2312 CHECK_DEL_REG_STR(props, "InstallSource", temp);
2313 CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2314 CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2315 CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2316 CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2317 CHECK_DEL_REG_STR(props, "Comments", NULL);
2318 CHECK_DEL_REG_STR(props, "Contact", NULL);
2319 CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2320 CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2321 CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2322 CHECK_DEL_REG_STR(props, "Readme", NULL);
2323 CHECK_DEL_REG_STR(props, "Size", NULL);
2324 CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2325 CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2326 CHECK_DEL_REG_DWORD(props, "Language", 1033);
2327 CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2328 CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2329 CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2330 CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2331 todo_wine
2332 {
2333 CHECK_DEL_REG_DWORD(props, "EstimatedSize", 12);
2334 }
2335
2336 RegDeleteKeyA(props, "");
2337 RegCloseKey(props);
2338
2339 res = RegOpenKeyA(hkey, "Usage", &usage);
2340 todo_wine
2341 {
2342 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2343 }
2344
2345 RegDeleteKeyA(usage, "");
2346 RegCloseKey(usage);
2347 RegDeleteKeyA(hkey, "");
2348 RegCloseKey(hkey);
2349
2350 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
2351 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2352
2353 CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2354
2355 RegDeleteKeyA(hkey, "");
2356 RegCloseKey(hkey);
2357
2358 /* RegisterProduct, machine */
2359 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
2360 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2361 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2362 ok(delete_pf("msitest", FALSE), "File not installed\n");
2363
2364 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, userugkey, &hkey);
2365 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2366
2367 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, uninstall, &hkey);
2368 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2369
2370 CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2371 CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2372 CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2373 CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2374 CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2375 CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2376 CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2377 CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2378 CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2379 CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2380 CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2381 CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2382 CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2383 CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2384 CHECK_DEL_REG_STR(hkey, "Size", NULL);
2385 CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2386 CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2387 CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2388 CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2389 CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2390 CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2391 CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2392 todo_wine
2393 {
2394 CHECK_DEL_REG_DWORD(hkey, "EstimatedSize", 12);
2395 }
2396
2397 RegDeleteKeyA(hkey, "");
2398 RegCloseKey(hkey);
2399
2400 sprintf(keypath, userdata, "S-1-5-18");
2401 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2402 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2403
2404 res = RegOpenKeyA(hkey, "InstallProperties", &props);
2405 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2406
2407 RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2408 CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2409 CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2410 CHECK_DEL_REG_STR(props, "InstallDate", date);
2411 CHECK_DEL_REG_STR(props, "InstallSource", temp);
2412 CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2413 CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2414 CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2415 CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2416 CHECK_DEL_REG_STR(props, "Comments", NULL);
2417 CHECK_DEL_REG_STR(props, "Contact", NULL);
2418 CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2419 CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2420 CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2421 CHECK_DEL_REG_STR(props, "Readme", NULL);
2422 CHECK_DEL_REG_STR(props, "Size", NULL);
2423 CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2424 CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2425 CHECK_DEL_REG_DWORD(props, "Language", 1033);
2426 CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2427 CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2428 CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2429 CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2430 todo_wine
2431 {
2432 CHECK_DEL_REG_DWORD(props, "EstimatedSize", 12);
2433 }
2434
2435 RegDeleteKeyA(props, "");
2436 RegCloseKey(props);
2437
2438 res = RegOpenKeyA(hkey, "Usage", &usage);
2439 todo_wine
2440 {
2441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2442 }
2443
2444 RegDeleteKeyA(usage, "");
2445 RegCloseKey(usage);
2446 RegDeleteKeyA(hkey, "");
2447 RegCloseKey(hkey);
2448
2449 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, ugkey, &hkey);
2450 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2451
2452 CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2453
2454 RegDeleteKeyA(hkey, "");
2455 RegCloseKey(hkey);
2456
2457 DeleteFile(msifile);
2458 DeleteFile("msitest\\maximus");
2459 RemoveDirectory("msitest");
2460 HeapFree(GetProcessHeap(), 0, usersid);
2461 }
2462
2463 static void test_publish_publishproduct(void)
2464 {
2465 UINT r;
2466 LONG res;
2467 LPSTR usersid;
2468 HKEY sourcelist, net, props;
2469 HKEY hkey, patches, media;
2470 CHAR keypath[MAX_PATH];
2471 CHAR temp[MAX_PATH];
2472 CHAR path[MAX_PATH];
2473
2474 static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2475 "\\Installer\\UserData\\%s\\Products"
2476 "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2477 static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
2478 "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2479 static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2480 "\\51AAE0C44620A5E4788506E91F249BD2";
2481 static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2482 "\\Installer\\Products"
2483 "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2484 static const CHAR machprod[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2485 static const CHAR machup[] = "Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2486
2487 get_user_sid(&usersid);
2488 if (!usersid)
2489 {
2490 skip("ConvertSidToStringSidA is not available\n");
2491 return;
2492 }
2493
2494 GetTempPath(MAX_PATH, temp);
2495
2496 CreateDirectoryA("msitest", NULL);
2497 create_file("msitest\\maximus", 500);
2498
2499 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2500
2501 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2502
2503 /* PublishProduct, current user */
2504 r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2505 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2506 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2507 ok(delete_pf("msitest", FALSE), "File not installed\n");
2508
2509 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
2510 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2511
2512 sprintf(keypath, prodpath, usersid);
2513 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2514 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2515
2516 res = RegOpenKeyA(hkey, "InstallProperties", &props);
2517 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2518
2519 res = RegOpenKeyA(hkey, "Patches", &patches);
2520 todo_wine
2521 {
2522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2523
2524 CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2525 }
2526
2527 RegDeleteKeyA(patches, "");
2528 RegCloseKey(patches);
2529 RegDeleteKeyA(hkey, "");
2530 RegCloseKey(hkey);
2531
2532 res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
2533 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2534
2535 CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2536 CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2537 CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2538 CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2539 CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2540 CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
2541 CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2542 CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2543 CHECK_DEL_REG_STR(hkey, "Clients", ":");
2544
2545 res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
2546 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2547
2548 lstrcpyA(path, "n;1;");
2549 lstrcatA(path, temp);
2550 CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2551 CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2552
2553 res = RegOpenKeyA(sourcelist, "Net", &net);
2554 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2555
2556 CHECK_DEL_REG_STR(net, "1", temp);
2557
2558 RegDeleteKeyA(net, "");
2559 RegCloseKey(net);
2560
2561 res = RegOpenKeyA(sourcelist, "Media", &media);
2562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2563
2564 CHECK_DEL_REG_STR(media, "1", "DISK1;");
2565
2566 RegDeleteKeyA(media, "");
2567 RegCloseKey(media);
2568 RegDeleteKeyA(sourcelist, "");
2569 RegCloseKey(sourcelist);
2570 RegDeleteKeyA(hkey, "");
2571 RegCloseKey(hkey);
2572
2573 res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
2574 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2575
2576 CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2577
2578 RegDeleteKeyA(hkey, "");
2579 RegCloseKey(hkey);
2580
2581 /* PublishProduct, machine */
2582 r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
2583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2584 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2585 ok(delete_pf("msitest", FALSE), "File not installed\n");
2586
2587 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, badprod, &hkey);
2588 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2589
2590 sprintf(keypath, prodpath, "S-1-5-18");
2591 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2593
2594 res = RegOpenKeyA(hkey, "InstallProperties", &props);
2595 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2596
2597 res = RegOpenKeyA(hkey, "Patches", &patches);
2598 todo_wine
2599 {
2600 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2601
2602 CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
2603 }
2604
2605 RegDeleteKeyA(patches, "");
2606 RegCloseKey(patches);
2607 RegDeleteKeyA(hkey, "");
2608 RegCloseKey(hkey);
2609
2610 res = RegOpenKeyA(HKEY_CLASSES_ROOT, machprod, &hkey);
2611 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2612
2613 CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
2614 CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052c94DA02821EECD05F2F");
2615 CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2616 CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2617 CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
2618 todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
2619 CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
2620 CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
2621 CHECK_DEL_REG_STR(hkey, "Clients", ":");
2622
2623 res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
2624 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2625
2626 lstrcpyA(path, "n;1;");
2627 lstrcatA(path, temp);
2628 CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
2629 CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
2630
2631 res = RegOpenKeyA(sourcelist, "Net", &net);
2632 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2633
2634 CHECK_DEL_REG_STR(net, "1", temp);
2635
2636 RegDeleteKeyA(net, "");
2637 RegCloseKey(net);
2638
2639 res = RegOpenKeyA(sourcelist, "Media", &media);
2640 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2641
2642 CHECK_DEL_REG_STR(media, "1", "DISK1;");
2643
2644 RegDeleteKeyA(media, "");
2645 RegCloseKey(media);
2646 RegDeleteKeyA(sourcelist, "");
2647 RegCloseKey(sourcelist);
2648 RegDeleteKeyA(hkey, "");
2649 RegCloseKey(hkey);
2650
2651 res = RegOpenKeyA(HKEY_CLASSES_ROOT, machup, &hkey);
2652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2653
2654 CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2655
2656 RegDeleteKeyA(hkey, "");
2657 RegCloseKey(hkey);
2658
2659 DeleteFile(msifile);
2660 DeleteFile("msitest\\maximus");
2661 RemoveDirectory("msitest");
2662 HeapFree(GetProcessHeap(), 0, usersid);
2663 }
2664
2665 static void test_publish_publishfeatures(void)
2666 {
2667 UINT r;
2668 LONG res;
2669 HKEY hkey;
2670 LPSTR usersid;
2671 CHAR keypath[MAX_PATH];
2672
2673 static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
2674 "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2675 static const CHAR udpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2676 "\\Installer\\UserData\\%s\\Products"
2677 "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
2678 static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2679 "\\Installer\\Features";
2680 static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
2681 "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2682
2683 get_user_sid(&usersid);
2684 if (!usersid)
2685 {
2686 skip("ConvertSidToStringSidA is not available\n");
2687 return;
2688 }
2689
2690 CreateDirectoryA("msitest", NULL);
2691 create_file("msitest\\maximus", 500);
2692
2693 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2694
2695 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2696
2697 /* PublishFeatures, current user */
2698 r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2700 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2701 ok(delete_pf("msitest", FALSE), "File not installed\n");
2702
2703 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
2704 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2705
2706 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
2707 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2708
2709 res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
2710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2711
2712 CHECK_REG_STR(hkey, "feature", "");
2713 CHECK_REG_STR(hkey, "montecristo", "");
2714
2715 RegDeleteValueA(hkey, "feature");
2716 RegDeleteValueA(hkey, "montecristo");
2717 RegDeleteKeyA(hkey, "");
2718 RegCloseKey(hkey);
2719
2720 sprintf(keypath, udpath, usersid);
2721 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2722 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2723
2724 CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
2725 CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
2726
2727 RegDeleteValueA(hkey, "feature");
2728 RegDeleteValueA(hkey, "montecristo");
2729 RegDeleteKeyA(hkey, "");
2730 RegCloseKey(hkey);
2731
2732 /* PublishFeatures, machine */
2733 r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
2734 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2735 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2736 ok(delete_pf("msitest", FALSE), "File not installed\n");
2737
2738 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
2739 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2740
2741 res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
2742 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2743
2744 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
2745 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2746
2747 CHECK_REG_STR(hkey, "feature", "");
2748 CHECK_REG_STR(hkey, "montecristo", "");
2749
2750 RegDeleteValueA(hkey, "feature");
2751 RegDeleteValueA(hkey, "montecristo");
2752 RegDeleteKeyA(hkey, "");
2753 RegCloseKey(hkey);
2754
2755 sprintf(keypath, udpath, "S-1-5-18");
2756 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
2757 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2758
2759 CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
2760 CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
2761
2762 RegDeleteValueA(hkey, "feature");
2763 RegDeleteValueA(hkey, "montecristo");
2764 RegDeleteKeyA(hkey, "");
2765 RegCloseKey(hkey);
2766
2767 DeleteFile(msifile);
2768 DeleteFile("msitest\\maximus");
2769 RemoveDirectory("msitest");
2770 HeapFree(GetProcessHeap(), 0, usersid);
2771 }
2772
2773 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
2774 {
2775 DWORD len = 0;
2776 LPSTR val;
2777 LONG r;
2778
2779 r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
2780 if (r != ERROR_SUCCESS)
2781 return NULL;
2782
2783 len += sizeof (WCHAR);
2784 val = HeapAlloc(GetProcessHeap(), 0, len);
2785 if (!val) return NULL;
2786 val[0] = 0;
2787 RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
2788 return val;
2789 }
2790
2791 static void get_owner_company(LPSTR *owner, LPSTR *company)
2792 {
2793 LONG res;
2794 HKEY hkey;
2795
2796 *owner = *company = NULL;
2797
2798 res = RegOpenKeyA(HKEY_CURRENT_USER,
2799 "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
2800 if (res == ERROR_SUCCESS)
2801 {
2802 *owner = reg_get_val_str(hkey, "DefName");
2803 *company = reg_get_val_str(hkey, "DefCompany");
2804 RegCloseKey(hkey);
2805 }
2806
2807 if (!*owner || !*company)
2808 {
2809 res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
2810 "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
2811 if (res == ERROR_SUCCESS)
2812 {
2813 *owner = reg_get_val_str(hkey, "RegisteredOwner");
2814 *company = reg_get_val_str(hkey, "RegisteredOrganization");
2815 RegCloseKey(hkey);
2816 }
2817 }
2818
2819 if (!*owner || !*company)
2820 {
2821 res = RegOpenKeyA(HKEY_LOCAL_MACHINE,
2822 "Software\\Microsoft\\Windows NT\\CurrentVersion", &hkey);
2823 if (res == ERROR_SUCCESS)
2824 {
2825 *owner = reg_get_val_str(hkey, "RegisteredOwner");
2826 *company = reg_get_val_str(hkey, "RegisteredOrganization");
2827 RegCloseKey(hkey);
2828 }
2829 }
2830 }
2831
2832 static void test_publish_registeruser(void)
2833 {
2834 UINT r;
2835 LONG res;
2836 HKEY props;
2837 LPSTR usersid;
2838 LPSTR owner, company;
2839 CHAR keypath[MAX_PATH];
2840
2841 static const CHAR keyfmt[] =
2842 "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
2843 "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
2844
2845 get_user_sid(&usersid);
2846 if (!usersid)
2847 {
2848 skip("ConvertSidToStringSidA is not available\n");
2849 return;
2850 }
2851
2852 get_owner_company(&owner, &company);
2853
2854 CreateDirectoryA("msitest", NULL);
2855 create_file("msitest\\maximus", 500);
2856
2857 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2858
2859 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2860
2861 /* RegisterUser, per-user */
2862 r = MsiInstallProductA(msifile, "REGISTER_USER=1");
2863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2864 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2865 ok(delete_pf("msitest", FALSE), "File not installed\n");
2866
2867 sprintf(keypath, keyfmt, usersid);
2868
2869 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
2870 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2871
2872 CHECK_REG_STR(props, "ProductID", "none");
2873 CHECK_REG_STR(props, "RegCompany", company);
2874 CHECK_REG_STR(props, "RegOwner", owner);
2875
2876 RegDeleteValueA(props, "ProductID");
2877 RegDeleteValueA(props, "RegCompany");
2878 RegDeleteValueA(props, "RegOwner");
2879 RegDeleteKeyA(props, "");
2880 RegCloseKey(props);
2881
2882 /* RegisterUser, machine */
2883 r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
2884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2885 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2886 ok(delete_pf("msitest", FALSE), "File not installed\n");
2887
2888 sprintf(keypath, keyfmt, "S-1-5-18");
2889
2890 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &props);
2891 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2892
2893 CHECK_REG_STR(props, "ProductID", "none");
2894 CHECK_REG_STR(props, "RegCompany", company);
2895 CHECK_REG_STR(props, "RegOwner", owner);
2896
2897 RegDeleteValueA(props, "ProductID");
2898 RegDeleteValueA(props, "RegCompany");
2899 RegDeleteValueA(props, "RegOwner");
2900 RegDeleteKeyA(props, "");
2901 RegCloseKey(props);
2902
2903 HeapFree(GetProcessHeap(), 0, company);
2904 HeapFree(GetProcessHeap(), 0, owner);
2905
2906 DeleteFile(msifile);
2907 DeleteFile("msitest\\maximus");
2908 RemoveDirectory("msitest");
2909 }
2910
2911 static void test_publish_processcomponents(void)
2912 {
2913 UINT r;
2914 LONG res;
2915 DWORD size;
2916 HKEY comp, hkey;
2917 LPSTR usersid;
2918 CHAR val[MAX_PATH];
2919 CHAR keypath[MAX_PATH];
2920
2921 static const CHAR keyfmt[] =
2922 "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
2923 "UserData\\%s\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5";
2924 static const CHAR compkey[] =
2925 "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
2926
2927 get_user_sid(&usersid);
2928 if (!usersid)
2929 {
2930 skip("ConvertSidToStringSidA is not available\n");
2931 return;
2932 }
2933
2934 CreateDirectoryA("msitest", NULL);
2935 create_file("msitest\\maximus", 500);
2936
2937 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2938
2939 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2940
2941 /* ProcessComponents, per-user */
2942 r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
2943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2944 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2945 ok(delete_pf("msitest", FALSE), "File not installed\n");
2946
2947 sprintf(keypath, keyfmt, usersid);
2948
2949 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
2950 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2951
2952 size = MAX_PATH;
2953 res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
2954 NULL, NULL, (LPBYTE)val, &size);
2955 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2956 ok(!lstrcmpA(val, "C:\\Program Files\\msitest\\maximus"),
2957 "Expected \"%s\", got \"%s\"\n", "C:\\Program Files\\msitest\\maximus", val);
2958
2959 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
2960 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2961
2962 RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
2963 RegDeleteKeyA(comp, "");
2964 RegCloseKey(comp);
2965
2966 /* ProcessComponents, machine */
2967 r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
2968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2969 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2970 ok(delete_pf("msitest", FALSE), "File not installed\n");
2971
2972 sprintf(keypath, keyfmt, "S-1-5-18");
2973
2974 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp);
2975 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2976
2977 size = MAX_PATH;
2978 res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
2979 NULL, NULL, (LPBYTE)val, &size);
2980 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2981 ok(!lstrcmpA(val, "C:\\Program Files\\msitest\\maximus"),
2982 "Expected \"%s\", got \"%s\"\n", "C:\\Program Files\\msitest\\maximus", val);
2983
2984 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey);
2985 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2986
2987 RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
2988 RegDeleteKeyA(comp, "");
2989 RegCloseKey(comp);
2990
2991 DeleteFile(msifile);
2992 DeleteFile("msitest\\maximus");
2993 RemoveDirectory("msitest");
2994 }
2995
2996 static void test_publish(void)
2997 {
2998 UINT r;
2999 LONG res;
3000 HKEY uninstall, prodkey;
3001 INSTALLSTATE state;
3002 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3003 char date[MAX_PATH];
3004 char temp[MAX_PATH];
3005
3006 static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3007
3008 if (!pMsiQueryComponentStateA)
3009 {
3010 skip("MsiQueryComponentStateA is not available\n");
3011 return;
3012 }
3013
3014 get_date_str(date);
3015 GetTempPath(MAX_PATH, temp);
3016
3017 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall);
3018 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3019
3020 CreateDirectoryA("msitest", NULL);
3021 create_file("msitest\\maximus", 500);
3022
3023 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3024
3025 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3026
3027 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3028 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3029
3030 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3031 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3032
3033 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3034 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3035
3036 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3037 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3038 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3039 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3040
3041 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3042 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3043
3044 /* nothing published */
3045 r = MsiInstallProductA(msifile, NULL);
3046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3047 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3048 ok(pf_exists("msitest"), "File not installed\n");
3049
3050 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3051 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3052
3053 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3054 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3055
3056 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3057 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3058
3059 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3060 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3061 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3062 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3063
3064 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3065 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3066
3067 /* PublishProduct and RegisterProduct */
3068 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
3069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3070 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3071 ok(pf_exists("msitest"), "File not installed\n");
3072
3073 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3074 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3075
3076 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3077 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3078
3079 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3080 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3081
3082 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3083 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3084 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3085 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3086
3087 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3088 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3089
3090 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3091 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3092 CHECK_REG_STR(prodkey, "InstallDate", date);
3093 CHECK_REG_STR(prodkey, "InstallSource", temp);
3094 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3095 CHECK_REG_STR(prodkey, "Publisher", "Wine");
3096 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3097 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3098 CHECK_REG_STR(prodkey, "Comments", NULL);
3099 CHECK_REG_STR(prodkey, "Contact", NULL);
3100 CHECK_REG_STR(prodkey, "HelpLink", NULL);
3101 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3102 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3103 CHECK_REG_STR(prodkey, "Readme", NULL);
3104 CHECK_REG_STR(prodkey, "Size", NULL);
3105 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3106 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3107 CHECK_REG_DWORD(prodkey, "Language", 1033);
3108 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3109 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3110 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3111 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3112 todo_wine
3113 {
3114 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3115 }
3116
3117 RegCloseKey(prodkey);
3118
3119 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3121 ok(pf_exists("msitest\\maximus"), "File deleted\n");
3122 ok(pf_exists("msitest"), "File deleted\n");
3123
3124 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3125 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3126
3127 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3128 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3129
3130 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3131 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3132
3133 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3134 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3135 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3136 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3137
3138 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3139 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3140
3141 /* complete install */
3142 r = MsiInstallProductA(msifile, "FULL=1");
3143 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3144 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3145 ok(pf_exists("msitest"), "File not installed\n");
3146
3147 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3148 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3149
3150 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3151 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3152
3153 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3154 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3155
3156 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3157 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3159 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3160
3161 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3162 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3163
3164 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3165 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3166 CHECK_REG_STR(prodkey, "InstallDate", date);
3167 CHECK_REG_STR(prodkey, "InstallSource", temp);
3168 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3169 CHECK_REG_STR(prodkey, "Publisher", "Wine");
3170 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3171 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3172 CHECK_REG_STR(prodkey, "Comments", NULL);
3173 CHECK_REG_STR(prodkey, "Contact", NULL);
3174 CHECK_REG_STR(prodkey, "HelpLink", NULL);
3175 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3176 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3177 CHECK_REG_STR(prodkey, "Readme", NULL);
3178 CHECK_REG_STR(prodkey, "Size", NULL);
3179 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3180 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3181 CHECK_REG_DWORD(prodkey, "Language", 1033);
3182 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3183 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3184 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3185 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3186 todo_wine
3187 {
3188 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3189 }
3190
3191 RegCloseKey(prodkey);
3192
3193 /* no UnpublishFeatures */
3194 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3196 todo_wine
3197 {
3198 ok(!pf_exists("msitest\\maximus"), "File deleted\n");
3199 ok(!pf_exists("msitest"), "File deleted\n");
3200 }
3201
3202 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3203 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3204
3205 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3206 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3207
3208 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3209 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3210
3211 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3212 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3213 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3214 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3215
3216 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3217 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3218
3219 /* complete install */
3220 r = MsiInstallProductA(msifile, "FULL=1");
3221 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3222 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3223 ok(pf_exists("msitest"), "File not installed\n");
3224
3225 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3226 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3227
3228 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3229 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3230
3231 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3232 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3233
3234 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3235 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3237 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3238
3239 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3240 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3241
3242 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3243 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3244 CHECK_REG_STR(prodkey, "InstallDate", date);
3245 CHECK_REG_STR(prodkey, "InstallSource", temp);
3246 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3247 CHECK_REG_STR(prodkey, "Publisher", "Wine");
3248 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3249 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3250 CHECK_REG_STR(prodkey, "Comments", NULL);
3251 CHECK_REG_STR(prodkey, "Contact", NULL);
3252 CHECK_REG_STR(prodkey, "HelpLink", NULL);
3253 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3254 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3255 CHECK_REG_STR(prodkey, "Readme", NULL);
3256 CHECK_REG_STR(prodkey, "Size", NULL);
3257 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3258 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3259 CHECK_REG_DWORD(prodkey, "Language", 1033);
3260 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3261 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3262 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3263 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3264 todo_wine
3265 {
3266 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3267 }
3268
3269 RegCloseKey(prodkey);
3270
3271 /* UnpublishFeatures, only feature removed. Only works when entire product is removed */
3272 r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
3273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3274 ok(pf_exists("msitest\\maximus"), "File deleted\n");
3275 ok(pf_exists("msitest"), "File deleted\n");
3276
3277 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3278 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3279
3280 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3281 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3282
3283 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3284 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3285
3286 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3287 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3289 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3290
3291 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3292 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3293
3294 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3295 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3296 CHECK_REG_STR(prodkey, "InstallDate", date);
3297 CHECK_REG_STR(prodkey, "InstallSource", temp);
3298 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3299 CHECK_REG_STR(prodkey, "Publisher", "Wine");
3300 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3301 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3302 CHECK_REG_STR(prodkey, "Comments", NULL);
3303 CHECK_REG_STR(prodkey, "Contact", NULL);
3304 CHECK_REG_STR(prodkey, "HelpLink", NULL);
3305 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3306 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3307 CHECK_REG_STR(prodkey, "Readme", NULL);
3308 CHECK_REG_STR(prodkey, "Size", NULL);
3309 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3310 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3311 CHECK_REG_DWORD(prodkey, "Language", 1033);
3312 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3313 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3314 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3315 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3316 todo_wine
3317 {
3318 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3319 }
3320
3321 RegCloseKey(prodkey);
3322
3323 /* complete install */
3324 r = MsiInstallProductA(msifile, "FULL=1");
3325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3327 ok(pf_exists("msitest"), "File not installed\n");
3328
3329 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3330 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3331
3332 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3333 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3334
3335 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3336 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3337
3338 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3339 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3341 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3342
3343 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3344 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3345
3346 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3347 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3348 CHECK_REG_STR(prodkey, "InstallDate", date);
3349 CHECK_REG_STR(prodkey, "InstallSource", temp);
3350 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3351 CHECK_REG_STR(prodkey, "Publisher", "Wine");
3352 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3353 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3354 CHECK_REG_STR(prodkey, "Comments", NULL);
3355 CHECK_REG_STR(prodkey, "Contact", NULL);
3356 CHECK_REG_STR(prodkey, "HelpLink", NULL);
3357 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3358 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3359 CHECK_REG_STR(prodkey, "Readme", NULL);
3360 CHECK_REG_STR(prodkey, "Size", NULL);
3361 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3362 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3363 CHECK_REG_DWORD(prodkey, "Language", 1033);
3364 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3365 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3366 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3367 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3368 todo_wine
3369 {
3370 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3371 }
3372
3373 RegCloseKey(prodkey);
3374
3375 /* UnpublishFeatures, both features removed */
3376 r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
3377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3378 todo_wine
3379 {
3380 ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3381 ok(!pf_exists("msitest"), "File not deleted\n");
3382 }
3383
3384 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3385 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3386
3387 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3388 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3389
3390 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3391 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3392
3393 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3394 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3395 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3396 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3397
3398 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3399 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3400
3401 /* complete install */
3402 r = MsiInstallProductA(msifile, "FULL=1");
3403 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3404 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3405 ok(pf_exists("msitest"), "File not installed\n");
3406
3407 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3408 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3409
3410 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3411 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3412
3413 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3414 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3415
3416 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3417 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3419 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3420
3421 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3422 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3423
3424 CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3425 CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3426 CHECK_REG_STR(prodkey, "InstallDate", date);
3427 CHECK_REG_STR(prodkey, "InstallSource", temp);
3428 CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3429 CHECK_REG_STR(prodkey, "Publisher", "Wine");
3430 CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3431 CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3432 CHECK_REG_STR(prodkey, "Comments", NULL);
3433 CHECK_REG_STR(prodkey, "Contact", NULL);
3434 CHECK_REG_STR(prodkey, "HelpLink", NULL);
3435 CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3436 CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3437 CHECK_REG_STR(prodkey, "Readme", NULL);
3438 CHECK_REG_STR(prodkey, "Size", NULL);
3439 CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3440 CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3441 CHECK_REG_DWORD(prodkey, "Language", 1033);
3442 CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3443 CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3444 CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3445 CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3446 todo_wine
3447 {
3448 CHECK_REG_DWORD(prodkey, "EstimatedSize", 12);
3449 }
3450
3451 RegCloseKey(prodkey);
3452
3453 /* complete uninstall */
3454 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3455 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3456 todo_wine
3457 {
3458 ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3459 ok(!pf_exists("msitest"), "File not deleted\n");
3460 }
3461
3462 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3463 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3464
3465 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
3466 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3467
3468 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
3469 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3470
3471 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3472 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3473 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3474 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3475
3476 res = RegOpenKeyA(uninstall, prodcode, &prodkey);
3477 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3478
3479 /* make sure 'Program Files\msitest' is removed */
3480 delete_pfmsitest_files();
3481
3482 RegCloseKey(uninstall);
3483 DeleteFile(msifile);
3484 DeleteFile("msitest\\maximus");
3485 RemoveDirectory("msitest");
3486 }
3487
3488 static void test_publishsourcelist(void)
3489 {
3490 UINT r;
3491 DWORD size;
3492 CHAR value[MAX_PATH];
3493 CHAR path[MAX_PATH];
3494 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3495
3496 if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
3497 {
3498 skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
3499 return;
3500 }
3501
3502 CreateDirectoryA("msitest", NULL);
3503 create_file("msitest\\maximus", 500);
3504
3505 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3506
3507 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3508
3509 r = MsiInstallProductA(msifile, NULL);
3510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3511 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3512 ok(pf_exists("msitest"), "File not installed\n");
3513
3514 /* nothing published */
3515 size = 0xdeadbeef;
3516 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3517 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3518 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3519 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3520
3521 size = 0xdeadbeef;
3522 r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3523 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3524 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3525 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3526
3527 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
3528 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3529 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3530 ok(pf_exists("msitest"), "File not installed\n");
3531
3532 /* after RegisterProduct */
3533 size = 0xdeadbeef;
3534 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3535 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3536 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3537 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3538
3539 size = 0xdeadbeef;
3540 r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3541 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3542 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3543 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3544
3545 r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3547 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3548 ok(pf_exists("msitest"), "File not installed\n");
3549
3550 /* after ProcessComponents */
3551 size = 0xdeadbeef;
3552 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3553 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3554 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3555 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3556
3557 size = 0xdeadbeef;
3558 r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3559 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3560 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3561 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3562
3563 r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3564 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3565 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3566 ok(pf_exists("msitest"), "File not installed\n");
3567
3568 /* after PublishFeatures */
3569 size = 0xdeadbeef;
3570 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3571 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
3572 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3573 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3574
3575 size = 0xdeadbeef;
3576 r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3577 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, &size);
3578 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3579 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
3580
3581 r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3582 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3583 ok(pf_exists("msitest\\maximus"), "File not installed\n");
3584 ok(pf_exists("msitest"), "File not installed\n");
3585
3586 /* after PublishProduct */
3587 size = MAX_PATH;
3588 lstrcpyA(value, "aaa");
3589 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3590 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
3591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3592 ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
3593 ok(size == 11, "Expected 11, got %d\n", size);
3594
3595 size = MAX_PATH;
3596 lstrcpyA(value, "aaa");
3597 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3598 MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
3599 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3600 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3601 ok(size == 0, "Expected 0, got %d\n", size);
3602
3603 size = MAX_PATH;
3604 lstrcpyA(value, "aaa");
3605 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3606 MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
3607 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3608 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
3609 ok(size == 0, "Expected 0, got %d\n", size);
3610
3611 lstrcpyA(path, CURR_DIR);
3612 lstrcatA(path, "\\");
3613
3614 size = MAX_PATH;
3615 lstrcpyA(value, "aaa");
3616 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3617 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
3618 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3619 ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3620 ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3621
3622 size = MAX_PATH;
3623 lstrcpyA(value, "aaa");
3624 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3625 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
3626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3627 ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
3628 ok(size == 1, "Expected 1, got %d\n", size);
3629
3630 size = MAX_PATH;
3631 lstrcpyA(value, "aaa");
3632 r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3633 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
3634 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3635 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3636 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3637
3638 size = MAX_PATH;
3639 lstrcpyA(value, "aaa");
3640 r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3641 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
3642 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3643 ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
3644 ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
3645
3646 size = MAX_PATH;
3647 lstrcpyA(value, "aaa");
3648 r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3649 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
3650 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3651 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
3652 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
3653
3654 /* complete uninstall */
3655 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3657 todo_wine
3658 {
3659 ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3660 ok(!pf_exists("msitest"), "File not deleted\n");
3661 }
3662
3663 /* make sure 'Program Files\msitest' is removed */
3664 delete_pfmsitest_files();
3665
3666 DeleteFile(msifile);
3667 DeleteFile("msitest\\maximus");
3668 RemoveDirectory("msitest");
3669 }
3670
3671 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
3672 {
3673 MSIHANDLE hview = 0;
3674 UINT r;
3675
3676 r = MsiDatabaseOpenView(hdb, query, &hview);
3677 if(r != ERROR_SUCCESS)
3678 return r;
3679
3680 r = MsiViewExecute(hview, hrec);
3681 if(r == ERROR_SUCCESS)
3682 r = MsiViewClose(hview);
3683 MsiCloseHandle(hview);
3684 return r;
3685 }
3686
3687 static void set_transform_summary_info(void)
3688 {
3689 UINT r;
3690 MSIHANDLE suminfo = 0;
3691
3692 /* build summary info */
3693 r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
3694 todo_wine
3695 {
3696 ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
3697 }
3698
3699 r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
3700 todo_wine
3701 {
3702 ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3703 }
3704
3705 r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
3706 "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3707 "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
3708 "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
3709 todo_wine
3710 {
3711 ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
3712 }
3713
3714 r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
3715 todo_wine
3716 {
3717 ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
3718 }
3719
3720 r = MsiSummaryInfoPersist(suminfo);
3721 todo_wine
3722 {
3723 ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
3724 }
3725
3726 r = MsiCloseHandle(suminfo);
3727 ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
3728 }
3729
3730 static void generate_transform(void)
3731 {
3732 MSIHANDLE hdb1, hdb2;
3733 LPCSTR query;
3734 UINT r;
3735
3736 /* start with two identical databases */
3737 CopyFile(msifile, msifile2, FALSE);
3738
3739 r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
3740 ok(r == ERROR_SUCCESS , "Failed to create database\n");
3741
3742 r = MsiDatabaseCommit(hdb1);
3743 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
3744
3745 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
3746 ok(r == ERROR_SUCCESS , "Failed to create database\n");
3747
3748 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
3749 r = run_query(hdb1, 0, query);
3750 ok(r == ERROR_SUCCESS, "failed to add property\n");
3751
3752 /* database needs to be committed */
3753 MsiDatabaseCommit(hdb1);
3754
3755 r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
3756 ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
3757
3758 #if 0 /* not implemented in wine yet */
3759 r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
3760 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3761 #endif
3762
3763 MsiCloseHandle(hdb1);
3764 MsiCloseHandle(hdb2);
3765 }
3766
3767 /* data for generating a transform */
3768
3769 /* tables transform names - encoded as they would be in an msi database file */
3770 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
3771 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
3772 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
3773
3774 /* data in each table */
3775 static const char data1[] = /* _StringData */
3776 "propval"; /* all the strings squashed together */
3777
3778 static const WCHAR data2[] = { /* _StringPool */
3779 /* len, refs */
3780 0, 0, /* string 0 '' */
3781 4, 1, /* string 1 'prop' */
3782 3, 1, /* string 2 'val' */
3783 };
3784
3785 static const WCHAR data3[] = { /* Property */
3786 0x0201, 0x0001, 0x0002,
3787 };
3788
3789 static const struct {
3790 LPCWSTR name;
3791 const void *data;
3792 DWORD size;
3793 } table_transform_data[] =
3794 {
3795 { name1, data1, sizeof data1 - 1 },
3796 { name2, data2, sizeof data2 },
3797 { name3, data3, sizeof data3 },
3798 };
3799
3800 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
3801
3802 static void generate_transform_manual(void)
3803 {
3804 IStorage *stg = NULL;
3805 IStream *stm;
3806 WCHAR name[0x20];
3807 HRESULT r;
3808 DWORD i, count;
3809 const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
3810
3811 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
3812
3813 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
3814
3815 r = StgCreateDocfile(name, mode, 0, &stg);
3816 ok(r == S_OK, "failed to create storage\n");
3817 if (!stg)
3818 return;
3819
3820 r = IStorage_SetClass(stg, &CLSID_MsiTransform);
3821 ok(r == S_OK, "failed to set storage type\n");
3822
3823 for (i=0; i<NUM_TRANSFORM_TABLES; i++)
3824 {
3825 r = IStorage_CreateStream(stg, table_transform_data[i].name,
3826 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3827 if (FAILED(r))
3828 {
3829 ok(0, "failed to create stream %08x\n", r);
3830 continue;
3831 }
3832
3833 r = IStream_Write(stm, table_transform_data[i].data,
3834 table_transform_data[i].size, &count);
3835 if (FAILED(r) || count != table_transform_data[i].size)
3836 ok(0, "failed to write stream\n");
3837 IStream_Release(stm);
3838 }
3839
3840 IStorage_Release(stg);
3841
3842 set_transform_summary_info();
3843 }
3844
3845 static void test_transformprop(void)
3846 {
3847 UINT r;
3848
3849 CreateDirectoryA("msitest", NULL);
3850 create_file("msitest\\augustus", 500);
3851
3852 create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
3853
3854 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3855
3856 r = MsiInstallProductA(msifile, NULL);
3857 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3858 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3859 ok(!delete_pf("msitest", FALSE), "File installed\n");
3860
3861 if (0)
3862 generate_transform();
3863 else
3864 generate_transform_manual();
3865
3866 r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
3867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3868 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3869 ok(delete_pf("msitest", FALSE), "File not installed\n");
3870
3871 /* Delete the files in the temp (current) folder */
3872 DeleteFile(msifile);
3873 DeleteFile(msifile2);
3874 DeleteFile(mstfile);
3875 DeleteFile("msitest\\augustus");
3876 RemoveDirectory("msitest");
3877 }
3878
3879 static void test_currentworkingdir(void)
3880 {
3881 UINT r;
3882 CHAR path[MAX_PATH];
3883 LPSTR ptr, ptr2;
3884
3885 CreateDirectoryA("msitest", NULL);
3886 create_file("msitest\\augustus", 500);
3887
3888 create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
3889
3890 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3891
3892 CreateDirectoryA("diffdir", NULL);
3893 SetCurrentDirectoryA("diffdir");
3894
3895 sprintf(path, "..\\%s", msifile);
3896 r = MsiInstallProductA(path, NULL);
3897 todo_wine
3898 {
3899 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
3900 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3901 ok(!delete_pf("msitest", FALSE), "File installed\n");
3902 }
3903
3904 sprintf(path, "%s\\%s", CURR_DIR, msifile);
3905 r = MsiInstallProductA(path, NULL);
3906 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3907 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3908 ok(delete_pf("msitest", FALSE), "File not installed\n");
3909
3910 lstrcpyA(path, CURR_DIR);
3911 if (path[lstrlenA(path) - 1] != '\\')
3912 lstrcatA(path, "\\");
3913 lstrcatA(path, "msitest.msi");
3914
3915 ptr2 = strrchr(path, '\\');
3916 *ptr2 = '\0';
3917 ptr = strrchr(path, '\\');
3918 *ptr2 = '\\';
3919 *(ptr++) = '\0';
3920
3921 SetCurrentDirectoryA(path);
3922
3923 r = MsiInstallProductA(ptr, NULL);
3924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3925 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
3926 ok(delete_pf("msitest", FALSE), "File not installed\n");
3927
3928 SetCurrentDirectoryA(CURR_DIR);
3929
3930 DeleteFile(msifile);
3931 DeleteFile("msitest\\augustus");
3932 RemoveDirectory("msitest");
3933 RemoveDirectory("diffdir");
3934 }
3935
3936 static void set_admin_summary_info(const CHAR *name)
3937 {
3938 MSIHANDLE db, summary;
3939 UINT r;
3940
3941 r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
3942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3943
3944 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
3945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3946
3947 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
3948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3949
3950 /* write the summary changes back to the stream */
3951 r = MsiSummaryInfoPersist(summary);
3952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3953
3954 MsiCloseHandle(summary);
3955
3956 r = MsiDatabaseCommit(db);
3957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3958
3959 MsiCloseHandle(db);
3960 }
3961
3962 static void test_admin(void)
3963 {
3964 UINT r;
3965
3966 CreateDirectoryA("msitest", NULL);
3967 create_file("msitest\\augustus", 500);
3968
3969 create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
3970 set_admin_summary_info(msifile);
3971
3972 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3973
3974 r = MsiInstallProductA(msifile, NULL);
3975 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3976 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3977 ok(!delete_pf("msitest", FALSE), "File installed\n");
3978 ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
3979 ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
3980
3981 r = MsiInstallProductA(msifile, "ACTION=ADMIN");
3982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3983 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
3984 ok(!delete_pf("msitest", FALSE), "File installed\n");
3985 todo_wine
3986 {
3987 ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
3988 ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
3989 }
3990
3991 DeleteFile(msifile);
3992 DeleteFile("msitest\\augustus");
3993 RemoveDirectory("msitest");
3994 }
3995
3996 static void set_admin_property_stream(LPCSTR file)
3997 {
3998 IStorage *stg;
3999 IStream *stm;
4000 WCHAR fileW[MAX_PATH];
4001 HRESULT hr;
4002 DWORD count;
4003 const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
4004
4005 /* AdminProperties */
4006 static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
4007 static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
4008
4009 MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
4010
4011 hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
4012 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4013 if (!stg)
4014 return;
4015
4016 hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
4017 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4018
4019 hr = IStream_Write(stm, data, sizeof(data), &count);
4020 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
4021
4022 IStream_Release(stm);
4023 IStorage_Release(stg);
4024 }
4025
4026 static void test_adminprops(void)
4027 {
4028 UINT r;
4029
4030 CreateDirectoryA("msitest", NULL);
4031 create_file("msitest\\augustus", 500);
4032
4033 create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
4034 set_admin_summary_info(msifile);
4035 set_admin_property_stream(msifile);
4036
4037 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4038
4039 r = MsiInstallProductA(msifile, NULL);
4040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4041 ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4042 ok(delete_pf("msitest", FALSE), "File installed\n");
4043
4044 DeleteFile(msifile);
4045 DeleteFile("msitest\\augustus");
4046 RemoveDirectory("msitest");
4047 }
4048
4049 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4050 {
4051 CHAR path[MAX_PATH];
4052
4053 lstrcpyA(path, PROG_FILES_DIR);
4054 lstrcatA(path, "\\");
4055 lstrcatA(path, file);
4056
4057 if (is_file)
4058 create_file_data(path, data, 500);
4059 else
4060 CreateDirectoryA(path, NULL);
4061 }
4062
4063 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4064
4065 static void test_removefiles(void)
4066 {
4067 UINT r;
4068
4069 CreateDirectoryA("msitest", NULL);
4070 create_file("msitest\\hydrogen", 500);
4071 create_file("msitest\\helium", 500);
4072 create_file("msitest\\lithium", 500);
4073
4074 create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4075
4076 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4077
4078 r = MsiInstallProductA(msifile, NULL);
4079 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4080 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4081 ok(!pf_exists("msitest\\helium"), "File installed\n");
4082 ok(pf_exists("msitest\\lithium"), "File not installed\n");
4083 ok(pf_exists("msitest"), "File not installed\n");
4084
4085 r = MsiInstallProductA(msifile, "REMOVE=ALL");
4086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4087 ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4088 ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4089 todo_wine
4090 {
4091 ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4092 ok(delete_pf("msitest", FALSE), "File deleted\n");
4093 }
4094
4095 create_pf("msitest", FALSE);
4096 create_pf("msitest\\hydrogen", TRUE);
4097 create_pf("msitest\\helium", TRUE);
4098 create_pf("msitest\\lithium", TRUE);
4099
4100 r = MsiInstallProductA(msifile, NULL);
4101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4102 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4103 ok(pf_exists("msitest\\helium"), "File not installed\n");
4104 ok(pf_exists("msitest\\lithium"), "File not installed\n");
4105 ok(pf_exists("msitest"), "File not installed\n");
4106
4107 r = MsiInstallProductA(msifile, "REMOVE=ALL");
4108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4109 ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4110 ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4111 todo_wine
4112 {
4113 ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4114 ok(delete_pf("msitest", FALSE), "File deleted\n");
4115 }
4116
4117 create_pf("msitest", FALSE);
4118 create_pf("msitest\\furlong", TRUE);
4119 create_pf("msitest\\firkin", TRUE);
4120 create_pf("msitest\\fortnight", TRUE);
4121 create_pf("msitest\\becquerel", TRUE);
4122 create_pf("msitest\\dioptre", TRUE);
4123 create_pf("msitest\\attoparsec", TRUE);
4124 create_pf("msitest\\storeys", TRUE);
4125 create_pf("msitest\\block", TRUE);
4126 create_pf("msitest\\siriometer", TRUE);
4127
4128 r = MsiInstallProductA(msifile, NULL);
4129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4130 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4131 ok(!pf_exists("msitest\\helium"), "File installed\n");
4132 ok(pf_exists("msitest\\lithium"), "File not installed\n");
4133 ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4134 ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4135 ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4136 ok(pf_exists("msitest"), "File not installed\n");
4137 todo_wine
4138 {
4139 ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4140 ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4141 ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4142 ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4143 ok(!pf_exists("msitest\\block"), "File not deleted\n");
4144 ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4145 }
4146
4147 create_pf("msitest\\furlong", TRUE);
4148 create_pf("msitest\\firkin", TRUE);
4149 create_pf("msitest\\fortnight", TRUE);
4150 create_pf("msitest\\storeys", TRUE);
4151 create_pf("msitest\\block", TRUE);
4152 create_pf("msitest\\siriometer", TRUE);
4153
4154 r = MsiInstallProductA(msifile, "REMOVE=ALL");
4155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4156 ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4157 ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4158 ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4159 ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4160 ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4161 ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4162 ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4163 todo_wine
4164 {
4165 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4166 ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4167 ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4168 ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4169 ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4170 }
4171 ok(delete_pf("msitest", FALSE), "File deleted\n");
4172
4173 DeleteFile(msifile);
4174 DeleteFile("msitest\\hydrogen");
4175 DeleteFile("msitest\\helium");
4176 DeleteFile("msitest\\lithium");
4177 RemoveDirectory("msitest");
4178 }
4179
4180 static void test_movefiles(void)
4181 {
4182 UINT r;
4183 char props[MAX_PATH];
4184
4185 CreateDirectoryA("msitest", NULL);
4186 create_file("msitest\\augustus", 100);
4187 create_file("cameroon", 100);
4188 create_file("djibouti", 100);
4189 create_file("egypt", 100);
4190 create_file("finland", 100);
4191 create_file("gambai", 100);
4192 create_file("honduras", 100);
4193 create_file("msitest\\india", 100);
4194 create_file("japan", 100);
4195 create_file("kenya", 100);
4196 CreateDirectoryA("latvia", NULL);
4197 create_file("nauru", 100);
4198 create_file("apple", 100);
4199 create_file("application", 100);
4200 create_file("ape", 100);
4201 create_file("foo", 100);
4202 create_file("fao", 100);
4203 create_file("fbod", 100);
4204 create_file("budding", 100);
4205 create_file("buddy", 100);
4206 create_file("bud", 100);
4207 create_file("bar", 100);
4208 create_file("bur", 100);
4209 create_file("bird", 100);
4210
4211 create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4212
4213 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
4214
4215 /* if the source or dest property is not a full path,
4216 * windows tries to access it as a network resource
4217 */
4218
4219 sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4220 "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4221 CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4222
4223 r = MsiInstallProductA(msifile, props);
4224 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4225 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4226 ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4227 ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4228 ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4229 ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4230 ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4231 ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4232 ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4233 ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4234 ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4235 ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4236 ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4237 ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4238 /* either apple or application will be moved depending on directory order */
4239 if (!delete_pf("msitest\\apple", TRUE))
4240 ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4241 else
4242 ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4243 ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4244 ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4245 /* either fao or foo will be moved depending on directory order */
4246 if (delete_pf("msitest\\foo", TRUE))
4247 ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4248 else
4249 ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4250 ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4251 ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4252 ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4253 ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4254 ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4255 ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4256 ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4257 ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4258 ok(delete_pf("msitest", FALSE), "File not installed\n");
4259 ok(DeleteFileA("cameroon"), "File moved\n");
4260 ok(!DeleteFileA("djibouti"), "File not moved\n");
4261 ok(DeleteFileA("egypt"), "File moved\n");
4262 ok(DeleteFileA("finland"), "File moved\n");
4263 ok(DeleteFileA("gambai"), "File moved\n");
4264 ok(!DeleteFileA("honduras"), "File not moved\n");
4265 ok(DeleteFileA("msitest\\india"), "File moved\n");
4266 ok(DeleteFileA("japan"), "File moved\n");
4267 ok(!DeleteFileA("kenya"), "File not moved\n");
4268 ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4269 ok(!DeleteFileA("nauru"), "File not moved\n");
4270 ok(!DeleteFileA("apple"), "File not moved\n");
4271 ok(!DeleteFileA("application"), "File not moved\n");
4272 ok(DeleteFileA("ape"), "File moved\n");
4273 ok(!DeleteFileA("foo"), "File not moved\n");
4274 ok(!DeleteFileA("fao"), "File not moved\n");
4275 ok(DeleteFileA("fbod"), "File moved\n");
4276 ok(!DeleteFileA("budding"), "File not moved\n");
4277 ok(!DeleteFileA("buddy"), "File not moved\n");
4278 ok(DeleteFileA("bud"), "File moved\n");
4279 ok(!DeleteFileA("bar"), "File not moved\n");
4280 ok(!DeleteFileA("bur"), "File not moved\n");
4281 ok(DeleteFileA("bird"), "File moved\n");
4282
4283 DeleteFile("msitest\\augustus");
4284 RemoveDirectory("msitest");
4285 DeleteFile(msifile);
4286 }
4287
4288 static void test_missingcab(void)
4289 {
4290 UINT r;
4291
4292 CreateDirectoryA("msitest", NULL);
4293 create_file("msitest\\augustus", 500);
4294 create_file("maximus", 500);
4295
4296 create_database(msifile, mc_tables, sizeof(mc_tables) / sizeof(msi_table));
4297
4298 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4299
4300 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
4301
4302 create_pf("msitest", FALSE);
4303 create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4304
4305 r = MsiInstallProductA(msifile, NULL);
4306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4307 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4308 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
4309 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4310 ok(!delete_pf("msitest\\gaius", TRUE), "File installed\n");
4311 ok(delete_pf("msitest", FALSE), "File not installed\n");
4312
4313 create_pf("msitest", FALSE);
4314 create_pf_data("msitest\\caesar", "abcdefgh", TRUE);
4315 create_pf("msitest\\gaius", TRUE);
4316
4317 r = MsiInstallProductA(msifile, "GAIUS=1");
4318 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4319 todo_wine
4320 {
4321 ok(!delete_pf("msitest\\maximus", TRUE), "File installed\n");
4322 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4323 }
4324 ok(delete_pf("msitest\\caesar", TRUE), "File removed\n");
4325 ok(delete_pf("msitest\\gaius", TRUE), "File removed\n");
4326 ok(delete_pf("msitest", FALSE), "File not installed\n");
4327
4328 DeleteFile("msitest\\augustus");
4329 RemoveDirectory("msitest");
4330 DeleteFile("maximus");
4331 DeleteFile("test1.cab");
4332 DeleteFile(msifile);
4333 }
4334
4335 static void test_duplicatefiles(void)
4336 {
4337 UINT r;
4338
4339 CreateDirectoryA("msitest", NULL);
4340 create_file("msitest\\maximus", 500);
4341 create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4342
4343 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4344
4345 /* fails if the destination folder is not a valid property */
4346
4347 r = MsiInstallProductA(msifile, NULL);
4348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4349 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4350 ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4351 ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4352 ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "File not duplicated\n");
4353 ok(delete_pf("msitest\\this\\doesnot", FALSE), "File not duplicated\n");
4354 ok(delete_pf("msitest\\this", FALSE), "File not duplicated\n");
4355 ok(delete_pf("msitest", FALSE), "File not installed\n");
4356
4357 DeleteFile("msitest\\maximus");
4358 RemoveDirectory("msitest");
4359 DeleteFile(msifile);
4360 }
4361
4362 static void test_writeregistryvalues(void)
4363 {
4364 UINT r;
4365 LONG res;
4366 HKEY hkey;
4367 DWORD type, size;
4368 CHAR path[MAX_PATH];
4369
4370 CreateDirectoryA("msitest", NULL);
4371 create_file("msitest\\augustus", 500);
4372
4373 create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4374
4375 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4376
4377 r = MsiInstallProductA(msifile, NULL);
4378 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4379 ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4380 ok(delete_pf("msitest", FALSE), "File installed\n");
4381
4382 res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
4383 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4384
4385 size = MAX_PATH;
4386 type = REG_MULTI_SZ;
4387 memset(path, 'a', MAX_PATH);
4388 res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4390 ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4391 ok(size == 15, "Expected 15, got %d\n", size);
4392 ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4393
4394 DeleteFile(msifile);
4395 DeleteFile("msitest\\augustus");
4396 RemoveDirectory("msitest");
4397
4398 RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
4399 RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine");
4400 }
4401
4402 static void test_sourcefolder(void)
4403 {
4404 UINT r;
4405
4406 CreateDirectoryA("msitest", NULL);
4407 create_file("augustus", 500);
4408
4409 create_database(msifile, sf_tables, sizeof(sf_tables) / sizeof(msi_table));
4410
4411 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4412
4413 r = MsiInstallProductA(msifile, NULL);
4414 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4415 todo_wine
4416 {
4417 ok(r == ERROR_INSTALL_FAILURE,
4418 "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4419 ok(!delete_pf("msitest", FALSE), "File installed\n");
4420 }
4421
4422 RemoveDirectoryA("msitest");
4423
4424 r = MsiInstallProductA(msifile, NULL);
4425 todo_wine
4426 {
4427 ok(r == ERROR_INSTALL_FAILURE,
4428 "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
4429 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
4430 ok(!delete_pf("msitest", FALSE), "File installed\n");
4431 }
4432
4433 DeleteFile(msifile);
4434 DeleteFile("augustus");
4435 }
4436
4437 static void test_customaction51(void)
4438 {
4439 UINT r;
4440
4441 CreateDirectoryA("msitest", NULL);
4442 create_file("msitest\\augustus", 500);
4443
4444 create_database(msifile, ca51_tables, sizeof(ca51_tables) / sizeof(msi_table));
4445
4446 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4447
4448 r = MsiInstallProductA(msifile, NULL);
4449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4450 ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4451 ok(delete_pf("msitest", FALSE), "File installed\n");
4452
4453 DeleteFile(msifile);
4454 DeleteFile("msitest\\augustus");
4455 RemoveDirectory("msitest");
4456 }
4457
4458 static void test_installstate(void)
4459 {
4460 UINT r;
4461
4462 CreateDirectoryA("msitest", NULL);
4463 create_file("msitest\\alpha", 500);
4464 create_file("msitest\\beta", 500);
4465 create_file("msitest\\gamma", 500);
4466 create_file("msitest\\theta", 500);
4467 create_file("msitest\\delta", 500);
4468 create_file("msitest\\epsilon", 500);
4469 create_file("msitest\\zeta", 500);
4470 create_file("msitest\\iota", 500);
4471 create_file("msitest\\eta", 500);
4472 create_file("msitest\\kappa", 500);
4473 create_file("msitest\\lambda", 500);
4474 create_file("msitest\\mu", 500);
4475
4476 create_database(msifile, is_tables, sizeof(is_tables) / sizeof(msi_table));
4477
4478 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4479
4480 r = MsiInstallProductA(msifile, NULL);
4481 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4482 ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4483 ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4484 ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4485 ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4486 ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4487 ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4488 ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4489 ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4490 ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4491 ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4492 ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4493 ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4494 ok(delete_pf("msitest", FALSE), "File not installed\n");
4495
4496 r = MsiInstallProductA(msifile, "ADDLOCAL=\"one,two,three,four\"");
4497 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4498 ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4499 ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4500 ok(delete_pf("msitest\\gamma", TRUE), "File not installed\n");
4501 ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4502 ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4503 ok(delete_pf("msitest\\epsilon", TRUE), "File not installed\n");
4504 ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4505 ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4506 ok(delete_pf("msitest\\eta", TRUE), "File not installed\n");
4507 ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4508 ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4509 ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4510 ok(delete_pf("msitest", FALSE), "File not installed\n");
4511
4512 r = MsiInstallProductA(msifile, "ADDSOURCE=\"one,two,three,four\"");
4513 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4514 ok(delete_pf("msitest\\alpha", TRUE), "File not installed\n");
4515 ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4516 ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4517 ok(delete_pf("msitest\\theta", TRUE), "File not installed\n");
4518 ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4519 ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4520 ok(delete_pf("msitest\\zeta", TRUE), "File not installed\n");
4521 ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4522 ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4523 ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4524 ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4525 ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4526 ok(delete_pf("msitest", FALSE), "File not installed\n");
4527
4528 r = MsiInstallProductA(msifile, "REMOVE=\"one,two,three,four\"");
4529 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4530 ok(!delete_pf("msitest\\alpha", TRUE), "File installed\n");
4531 ok(!delete_pf("msitest\\beta", TRUE), "File installed\n");
4532 ok(!delete_pf("msitest\\gamma", TRUE), "File installed\n");
4533 ok(!delete_pf("msitest\\theta", TRUE), "File installed\n");
4534 ok(!delete_pf("msitest\\delta", TRUE), "File installed\n");
4535 ok(!delete_pf("msitest\\epsilon", TRUE), "File installed\n");
4536 ok(!delete_pf("msitest\\zeta", TRUE), "File installed\n");
4537 ok(!delete_pf("msitest\\iota", TRUE), "File installed\n");
4538 ok(!delete_pf("msitest\\eta", TRUE), "File installed\n");
4539 ok(!delete_pf("msitest\\kappa", TRUE), "File installed\n");
4540 ok(!delete_pf("msitest\\lambda", TRUE), "File installed\n");
4541 ok(!delete_pf("msitest\\mu", TRUE), "File installed\n");
4542 ok(!delete_pf("msitest", FALSE), "File installed\n");
4543
4544 DeleteFile(msifile);
4545 DeleteFile("msitest\\alpha");
4546 DeleteFile("msitest\\beta");
4547 DeleteFile("msitest\\gamma");
4548 DeleteFile("msitest\\theta");
4549 DeleteFile("msitest\\delta");
4550 DeleteFile("msitest\\epsilon");
4551 DeleteFile("msitest\\zeta");
4552 DeleteFile("msitest\\iota");
4553 DeleteFile("msitest\\eta");
4554 DeleteFile("msitest\\kappa");
4555 DeleteFile("msitest\\lambda");
4556 DeleteFile("msitest\\mu");
4557 RemoveDirectory("msitest");
4558 }
4559
4560 START_TEST(install)
4561 {
4562 DWORD len;
4563 char temp_path[MAX_PATH], prev_path[MAX_PATH];
4564
4565 init_functionpointers();
4566
4567 GetCurrentDirectoryA(MAX_PATH, prev_path);
4568 GetTempPath(MAX_PATH, temp_path);
4569 SetCurrentDirectoryA(temp_path);
4570
4571 lstrcpyA(CURR_DIR, temp_path);
4572 len = lstrlenA(CURR_DIR);
4573
4574 if(len && (CURR_DIR[len - 1] == '\\'))
4575 CURR_DIR[len - 1] = 0;
4576
4577 get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
4578
4579 test_MsiInstallProduct();
4580 test_MsiSetComponentState();
4581 test_packagecoltypes();
4582 test_continuouscabs();
4583 test_caborder();
4584 test_mixedmedia();
4585 test_samesequence();
4586 test_uiLevelFlags();
4587 test_readonlyfile();
4588 test_setdirproperty();
4589 test_cabisextracted();
4590 test_concurrentinstall();
4591 test_setpropertyfolder();
4592 test_publish_registerproduct();
4593 test_publish_publishproduct();
4594 test_publish_publishfeatures();
4595 test_publish_registeruser();
4596 test_publish_processcomponents();
4597 test_publish();
4598 test_publishsourcelist();
4599 test_transformprop();
4600 test_currentworkingdir();
4601 test_admin();
4602 test_adminprops();
4603 test_removefiles();
4604 test_movefiles();
4605 test_missingcab();
4606 test_duplicatefiles();
4607 test_writeregistryvalues();
4608 test_sourcefolder();
4609 test_customaction51();
4610 test_installstate();
4611
4612 SetCurrentDirectoryA(prev_path);
4613 }