push 3de9b6d6ec9c4ab8dfeeb76c2f7fb86ab1d5c9a7
[wine/hacks.git] / dlls / msi / tests / install.c
blob52de3db736b0b47436e21b9871b79c202a2ef847
1 /*
2 * Copyright (C) 2006 James Hawkins
4 * A test program for installing MSI products.
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.
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.
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
21 #define _WIN32_MSI 300
22 #define COBJMACROS
24 #include <stdio.h>
26 #include <windows.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <msi.h>
30 #include <fci.h>
31 #include <objidl.h>
33 #include "wine/test.h"
35 static UINT (WINAPI *pMsiQueryComponentStateA)
36 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
37 static UINT (WINAPI *pMsiSourceListGetInfoA)
38 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
40 static const char *msifile = "msitest.msi";
41 static const char *msifile2 = "winetest2.msi";
42 static const char *mstfile = "winetest.mst";
43 static CHAR CURR_DIR[MAX_PATH];
44 static CHAR PROG_FILES_DIR[MAX_PATH];
45 static CHAR COMMON_FILES_DIR[MAX_PATH];
47 /* msi database data */
49 static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
50 "s72\tS38\ts72\ti2\tS255\tS72\n"
51 "Component\tComponent\n"
52 "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
53 "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
54 "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\t\tone.txt\n"
55 "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
56 "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
57 "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
58 "component\t\tMSITESTDIR\t0\t1\tfile\n"
59 "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
61 static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
62 "s72\tS72\tl255\n"
63 "Directory\tDirectory\n"
64 "CABOUTDIR\tMSITESTDIR\tcabout\n"
65 "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
66 "FIRSTDIR\tMSITESTDIR\tfirst\n"
67 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
68 "NEWDIR\tCABOUTDIR\tnew\n"
69 "ProgramFilesFolder\tTARGETDIR\t.\n"
70 "TARGETDIR\t\tSourceDir";
72 static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
73 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
74 "Feature\tFeature\n"
75 "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
76 "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
77 "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
78 "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
79 "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
80 "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
81 "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
83 static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
84 "s38\ts72\n"
85 "FeatureComponents\tFeature_\tComponent_\n"
86 "Five\tFive\n"
87 "Four\tFour\n"
88 "One\tOne\n"
89 "Three\tThree\n"
90 "Two\tTwo\n"
91 "feature\tcomponent\n"
92 "service_feature\tservice_comp\n";
94 static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
95 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
96 "File\tFile\n"
97 "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
98 "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
99 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
100 "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
101 "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
102 "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
103 "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
105 static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
106 "s72\tS255\tI2\n"
107 "InstallExecuteSequence\tAction\n"
108 "AllocateRegistrySpace\tNOT Installed\t1550\n"
109 "CostFinalize\t\t1000\n"
110 "CostInitialize\t\t800\n"
111 "FileCost\t\t900\n"
112 "InstallFiles\t\t4000\n"
113 "InstallServices\t\t5000\n"
114 "InstallFinalize\t\t6600\n"
115 "InstallInitialize\t\t1500\n"
116 "InstallValidate\t\t1400\n"
117 "LaunchConditions\t\t100\n"
118 "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
120 static const CHAR media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
121 "i2\ti4\tL64\tS255\tS32\tS72\n"
122 "Media\tDiskId\n"
123 "1\t3\t\t\tDISK1\t\n"
124 "2\t5\t\tmsitest.cab\tDISK2\t\n";
126 static const CHAR property_dat[] = "Property\tValue\n"
127 "s72\tl0\n"
128 "Property\tProperty\n"
129 "DefaultUIFont\tDlgFont8\n"
130 "HASUIRUN\t0\n"
131 "INSTALLLEVEL\t3\n"
132 "InstallMode\tTypical\n"
133 "Manufacturer\tWine\n"
134 "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
135 "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
136 "ProductID\tnone\n"
137 "ProductLanguage\t1033\n"
138 "ProductName\tMSITEST\n"
139 "ProductVersion\t1.1.1\n"
140 "PROMPTROLLBACKCOST\tP\n"
141 "Setup\tSetup\n"
142 "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
143 "AdminProperties\tPOSTADMIN\n"
144 "ROOTDRIVE\tC:\\\n";
146 static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
147 "s72\ti2\tl255\tL255\tL0\ts72\n"
148 "Registry\tRegistry\n"
149 "Apples\t2\tSOFTWARE\\Wine\\msitest\tName\timaname\tOne\n"
150 "Oranges\t2\tSOFTWARE\\Wine\\msitest\tnumber\t#314\tTwo\n"
151 "regdata\t2\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
152 "OrderTest\t2\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
154 static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
155 "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
156 "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
157 "ServiceInstall\tServiceInstall\n"
158 "TestService\tTestService\tTestService\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
160 static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
161 "s72\tl255\ti2\tL255\tI2\ts72\n"
162 "ServiceControl\tServiceControl\n"
163 "ServiceControl\tTestService\t8\t\t0\tservice_comp";
165 /* tables for test_continuouscabs */
166 static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
167 "s72\tS38\ts72\ti2\tS255\tS72\n"
168 "Component\tComponent\n"
169 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
170 "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
171 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
173 static const CHAR cc_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
174 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
175 "Feature\tFeature\n"
176 "feature\t\t\t\t2\t1\tTARGETDIR\t0";
178 static const CHAR cc_feature_comp_dat[] = "Feature_\tComponent_\n"
179 "s38\ts72\n"
180 "FeatureComponents\tFeature_\tComponent_\n"
181 "feature\tmaximus\n"
182 "feature\taugustus\n"
183 "feature\tcaesar";
185 static const CHAR cc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
186 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
187 "File\tFile\n"
188 "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
189 "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
190 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12";
192 static const CHAR cc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
193 "i2\ti4\tL64\tS255\tS32\tS72\n"
194 "Media\tDiskId\n"
195 "1\t10\t\ttest1.cab\tDISK1\t\n"
196 "2\t2\t\ttest2.cab\tDISK2\t\n"
197 "3\t12\t\ttest3.cab\tDISK3\t\n";
199 static const CHAR co_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\t3";
206 static const CHAR co_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
207 "i2\ti4\tL64\tS255\tS32\tS72\n"
208 "Media\tDiskId\n"
209 "1\t10\t\ttest1.cab\tDISK1\t\n"
210 "2\t2\t\ttest2.cab\tDISK2\t\n"
211 "3\t3\t\ttest3.cab\tDISK3\t\n";
213 static const CHAR co2_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
214 "i2\ti4\tL64\tS255\tS32\tS72\n"
215 "Media\tDiskId\n"
216 "1\t10\t\ttest1.cab\tDISK1\t\n"
217 "2\t12\t\ttest3.cab\tDISK3\t\n"
218 "3\t2\t\ttest2.cab\tDISK2\t\n";
220 static const CHAR mm_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
221 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
222 "File\tFile\n"
223 "maximus\tmaximus\tmaximus\t500\t\t\t512\t1\n"
224 "augustus\taugustus\taugustus\t500\t\t\t512\t2\n"
225 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t3";
227 static const CHAR mm_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
228 "i2\ti4\tL64\tS255\tS32\tS72\n"
229 "Media\tDiskId\n"
230 "1\t3\t\ttest1.cab\tDISK1\t\n";
232 static const CHAR ss_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
233 "i2\ti4\tL64\tS255\tS32\tS72\n"
234 "Media\tDiskId\n"
235 "1\t2\t\ttest1.cab\tDISK1\t\n"
236 "2\t2\t\ttest2.cab\tDISK2\t\n"
237 "3\t12\t\ttest3.cab\tDISK3\t\n";
239 /* tables for test_uiLevelFlags */
240 static const CHAR ui_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
241 "s72\tS38\ts72\ti2\tS255\tS72\n"
242 "Component\tComponent\n"
243 "maximus\t\tMSITESTDIR\t0\tHASUIRUN=1\tmaximus\n"
244 "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
245 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n";
247 static const CHAR ui_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
248 "s72\tS255\tI2\n"
249 "InstallUISequence\tAction\n"
250 "SetUIProperty\t\t5\n"
251 "ExecuteAction\t\t1100\n";
253 static const CHAR ui_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
254 "s72\ti2\tS64\tS0\tS255\n"
255 "CustomAction\tAction\n"
256 "SetUIProperty\t51\tHASUIRUN\t1\t\n";
258 static const CHAR rof_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
259 "s72\tS38\ts72\ti2\tS255\tS72\n"
260 "Component\tComponent\n"
261 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
263 static const CHAR rof_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
264 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
265 "Feature\tFeature\n"
266 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
267 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
269 static const CHAR rof_feature_comp_dat[] = "Feature_\tComponent_\n"
270 "s38\ts72\n"
271 "FeatureComponents\tFeature_\tComponent_\n"
272 "feature\tmaximus\n"
273 "montecristo\tmaximus";
275 static const CHAR rof_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
276 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
277 "File\tFile\n"
278 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
280 static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
281 "i2\ti4\tL64\tS255\tS32\tS72\n"
282 "Media\tDiskId\n"
283 "1\t1\t\t\tDISK1\t\n";
285 static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
286 "s72\tS255\tI2\n"
287 "InstallExecuteSequence\tAction\n"
288 "AllocateRegistrySpace\tNOT Installed\t1550\n"
289 "CostFinalize\t\t1000\n"
290 "CostInitialize\t\t800\n"
291 "FileCost\t\t900\n"
292 "InstallFiles\t\t4000\n"
293 "InstallFinalize\t\t6600\n"
294 "InstallInitialize\t\t1500\n"
295 "InstallValidate\t\t1400\n"
296 "LaunchConditions\t\t100\n"
297 "SetDirProperty\t\t950";
299 static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
300 "s72\ti2\tS64\tS0\tS255\n"
301 "CustomAction\tAction\n"
302 "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n";
304 static const CHAR cie_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
305 "s72\tS38\ts72\ti2\tS255\tS72\n"
306 "Component\tComponent\n"
307 "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n"
308 "augustus\t\tMSITESTDIR\t0\t1\taugustus\n"
309 "caesar\t\tMSITESTDIR\t0\t1\tcaesar\n"
310 "gaius\t\tMSITESTDIR\t0\t1\tgaius\n";
312 static const CHAR cie_feature_comp_dat[] = "Feature_\tComponent_\n"
313 "s38\ts72\n"
314 "FeatureComponents\tFeature_\tComponent_\n"
315 "feature\tmaximus\n"
316 "feature\taugustus\n"
317 "feature\tcaesar\n"
318 "feature\tgaius";
320 static const CHAR cie_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
321 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
322 "File\tFile\n"
323 "maximus\tmaximus\tmaximus\t500\t\t\t16384\t1\n"
324 "augustus\taugustus\taugustus\t50000\t\t\t16384\t2\n"
325 "caesar\tcaesar\tcaesar\t500\t\t\t16384\t12\n"
326 "gaius\tgaius\tgaius\t500\t\t\t8192\t11";
328 static const CHAR cie_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
329 "i2\ti4\tL64\tS255\tS32\tS72\n"
330 "Media\tDiskId\n"
331 "1\t1\t\ttest1.cab\tDISK1\t\n"
332 "2\t2\t\ttest2.cab\tDISK2\t\n"
333 "3\t12\t\ttest3.cab\tDISK3\t\n";
335 static const CHAR ci_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
336 "s72\tS255\tI2\n"
337 "InstallExecuteSequence\tAction\n"
338 "CostFinalize\t\t1000\n"
339 "CostInitialize\t\t800\n"
340 "FileCost\t\t900\n"
341 "InstallFiles\t\t4000\n"
342 "InstallServices\t\t5000\n"
343 "InstallFinalize\t\t6600\n"
344 "InstallInitialize\t\t1500\n"
345 "RunInstall\t\t1600\n"
346 "InstallValidate\t\t1400\n"
347 "LaunchConditions\t\t100";
349 static const CHAR ci_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
350 "s72\ti2\tS64\tS0\tS255\n"
351 "CustomAction\tAction\n"
352 "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
354 static const CHAR ci_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
355 "s72\tS38\ts72\ti2\tS255\tS72\n"
356 "Component\tComponent\n"
357 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
359 static const CHAR ci2_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
360 "s72\tS38\ts72\ti2\tS255\tS72\n"
361 "Component\tComponent\n"
362 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
364 static const CHAR ci2_feature_comp_dat[] = "Feature_\tComponent_\n"
365 "s38\ts72\n"
366 "FeatureComponents\tFeature_\tComponent_\n"
367 "feature\taugustus";
369 static const CHAR ci2_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
370 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
371 "File\tFile\n"
372 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
374 static const CHAR spf_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
375 "s72\ti2\tS64\tS0\tS255\n"
376 "CustomAction\tAction\n"
377 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
379 static const CHAR spf_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
380 "s72\tS255\tI2\n"
381 "InstallExecuteSequence\tAction\n"
382 "CostFinalize\t\t1000\n"
383 "CostInitialize\t\t800\n"
384 "FileCost\t\t900\n"
385 "SetFolderProp\t\t950\n"
386 "InstallFiles\t\t4000\n"
387 "InstallServices\t\t5000\n"
388 "InstallFinalize\t\t6600\n"
389 "InstallInitialize\t\t1500\n"
390 "InstallValidate\t\t1400\n"
391 "LaunchConditions\t\t100";
393 static const CHAR spf_install_ui_seq_dat[] = "Action\tCondition\tSequence\n"
394 "s72\tS255\tI2\n"
395 "InstallUISequence\tAction\n"
396 "CostInitialize\t\t800\n"
397 "FileCost\t\t900\n"
398 "CostFinalize\t\t1000\n"
399 "ExecuteAction\t\t1100\n";
401 static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
402 "s72\tS255\tI2\n"
403 "InstallExecuteSequence\tAction\n"
404 "ValidateProductID\t\t700\n"
405 "CostInitialize\t\t800\n"
406 "FileCost\t\t900\n"
407 "CostFinalize\t\t1000\n"
408 "InstallValidate\t\t1400\n"
409 "InstallInitialize\t\t1500\n"
410 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
411 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
412 "RemoveFiles\t\t3500\n"
413 "InstallFiles\t\t4000\n"
414 "RegisterUser\t\t6000\n"
415 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
416 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
417 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
418 "InstallFinalize\t\t6600";
420 static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
421 "s72\tS38\ts72\ti2\tS255\tS72\n"
422 "Component\tComponent\n"
423 "augustus\t\tMSITESTDIR\t0\tprop=\"val\"\taugustus\n";
425 static const CHAR cwd_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
426 "s72\tS38\ts72\ti2\tS255\tS72\n"
427 "Component\tComponent\n"
428 "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
430 static const CHAR adm_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
431 "s72\tS38\ts72\ti2\tS255\tS72\n"
432 "Component\tComponent\n"
433 "augustus\t\tMSITESTDIR\t0\tPOSTADMIN=1\taugustus";
435 static const CHAR adm_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n"
436 "s72\ti2\tS64\tS0\tS255\n"
437 "CustomAction\tAction\n"
438 "SetPOSTADMIN\t51\tPOSTADMIN\t1\t\n";
440 static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
441 "s72\tS255\tI2\n"
442 "AdminExecuteSequence\tAction\n"
443 "CostFinalize\t\t1000\n"
444 "CostInitialize\t\t800\n"
445 "FileCost\t\t900\n"
446 "SetPOSTADMIN\t\t950\n"
447 "InstallFiles\t\t4000\n"
448 "InstallFinalize\t\t6600\n"
449 "InstallInitialize\t\t1500\n"
450 "InstallValidate\t\t1400\n"
451 "LaunchConditions\t\t100";
453 static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
454 "s72\tS38\ts72\ti2\tS255\tS72\n"
455 "Component\tComponent\n"
456 "augustus\t\tMSITESTDIR\t0\tMYPROP=2718\taugustus\n";
458 static const CHAR rem_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
459 "s72\tS38\ts72\ti2\tS255\tS72\n"
460 "Component\tComponent\n"
461 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
462 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
463 "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
465 static const CHAR rem_feature_comp_dat[] = "Feature_\tComponent_\n"
466 "s38\ts72\n"
467 "FeatureComponents\tFeature_\tComponent_\n"
468 "feature\thydrogen\n"
469 "feature\thelium\n"
470 "feature\tlithium";
472 static const CHAR rem_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
473 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
474 "File\tFile\n"
475 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
476 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
477 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
479 static const CHAR rem_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
480 "s72\tS255\tI2\n"
481 "InstallExecuteSequence\tAction\n"
482 "ValidateProductID\t\t700\n"
483 "CostInitialize\t\t800\n"
484 "FileCost\t\t900\n"
485 "CostFinalize\t\t1000\n"
486 "InstallValidate\t\t1400\n"
487 "InstallInitialize\t\t1500\n"
488 "ProcessComponents\t\t1600\n"
489 "UnpublishFeatures\t\t1800\n"
490 "RemoveFiles\t\t3500\n"
491 "InstallFiles\t\t4000\n"
492 "RegisterUser\t\t6000\n"
493 "RegisterProduct\t\t6100\n"
494 "PublishFeatures\t\t6300\n"
495 "PublishProduct\t\t6400\n"
496 "InstallFinalize\t\t6600";
498 static const CHAR rem_remove_files_dat[] = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
499 "s72\ts72\tS255\ts72\tI2\n"
500 "RemoveFile\tFileKey\n"
501 "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
502 "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
503 "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
504 "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
505 "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
506 "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
507 "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
508 "block\thelium\tblock\tMSITESTDIR\t3\n"
509 "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n";
511 typedef struct _msi_table
513 const CHAR *filename;
514 const CHAR *data;
515 int size;
516 } msi_table;
518 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
520 static const msi_table tables[] =
522 ADD_TABLE(component),
523 ADD_TABLE(directory),
524 ADD_TABLE(feature),
525 ADD_TABLE(feature_comp),
526 ADD_TABLE(file),
527 ADD_TABLE(install_exec_seq),
528 ADD_TABLE(media),
529 ADD_TABLE(property),
530 ADD_TABLE(registry),
531 ADD_TABLE(service_install),
532 ADD_TABLE(service_control)
535 static const msi_table cc_tables[] =
537 ADD_TABLE(cc_component),
538 ADD_TABLE(directory),
539 ADD_TABLE(cc_feature),
540 ADD_TABLE(cc_feature_comp),
541 ADD_TABLE(cc_file),
542 ADD_TABLE(install_exec_seq),
543 ADD_TABLE(cc_media),
544 ADD_TABLE(property),
547 static const msi_table co_tables[] =
549 ADD_TABLE(cc_component),
550 ADD_TABLE(directory),
551 ADD_TABLE(cc_feature),
552 ADD_TABLE(cc_feature_comp),
553 ADD_TABLE(co_file),
554 ADD_TABLE(install_exec_seq),
555 ADD_TABLE(co_media),
556 ADD_TABLE(property),
559 static const msi_table co2_tables[] =
561 ADD_TABLE(cc_component),
562 ADD_TABLE(directory),
563 ADD_TABLE(cc_feature),
564 ADD_TABLE(cc_feature_comp),
565 ADD_TABLE(cc_file),
566 ADD_TABLE(install_exec_seq),
567 ADD_TABLE(co2_media),
568 ADD_TABLE(property),
571 static const msi_table mm_tables[] =
573 ADD_TABLE(cc_component),
574 ADD_TABLE(directory),
575 ADD_TABLE(cc_feature),
576 ADD_TABLE(cc_feature_comp),
577 ADD_TABLE(mm_file),
578 ADD_TABLE(install_exec_seq),
579 ADD_TABLE(mm_media),
580 ADD_TABLE(property),
583 static const msi_table ss_tables[] =
585 ADD_TABLE(cc_component),
586 ADD_TABLE(directory),
587 ADD_TABLE(cc_feature),
588 ADD_TABLE(cc_feature_comp),
589 ADD_TABLE(cc_file),
590 ADD_TABLE(install_exec_seq),
591 ADD_TABLE(ss_media),
592 ADD_TABLE(property),
595 static const msi_table ui_tables[] =
597 ADD_TABLE(ui_component),
598 ADD_TABLE(directory),
599 ADD_TABLE(cc_feature),
600 ADD_TABLE(cc_feature_comp),
601 ADD_TABLE(cc_file),
602 ADD_TABLE(install_exec_seq),
603 ADD_TABLE(ui_install_ui_seq),
604 ADD_TABLE(ui_custom_action),
605 ADD_TABLE(cc_media),
606 ADD_TABLE(property),
609 static const msi_table rof_tables[] =
611 ADD_TABLE(rof_component),
612 ADD_TABLE(directory),
613 ADD_TABLE(rof_feature),
614 ADD_TABLE(rof_feature_comp),
615 ADD_TABLE(rof_file),
616 ADD_TABLE(install_exec_seq),
617 ADD_TABLE(rof_media),
618 ADD_TABLE(property),
621 static const msi_table sdp_tables[] =
623 ADD_TABLE(rof_component),
624 ADD_TABLE(directory),
625 ADD_TABLE(rof_feature),
626 ADD_TABLE(rof_feature_comp),
627 ADD_TABLE(rof_file),
628 ADD_TABLE(sdp_install_exec_seq),
629 ADD_TABLE(sdp_custom_action),
630 ADD_TABLE(rof_media),
631 ADD_TABLE(property),
634 static const msi_table cie_tables[] =
636 ADD_TABLE(cie_component),
637 ADD_TABLE(directory),
638 ADD_TABLE(cc_feature),
639 ADD_TABLE(cie_feature_comp),
640 ADD_TABLE(cie_file),
641 ADD_TABLE(install_exec_seq),
642 ADD_TABLE(cie_media),
643 ADD_TABLE(property),
646 static const msi_table ci_tables[] =
648 ADD_TABLE(ci_component),
649 ADD_TABLE(directory),
650 ADD_TABLE(rof_feature),
651 ADD_TABLE(rof_feature_comp),
652 ADD_TABLE(rof_file),
653 ADD_TABLE(ci_install_exec_seq),
654 ADD_TABLE(rof_media),
655 ADD_TABLE(property),
656 ADD_TABLE(ci_custom_action),
659 static const msi_table ci2_tables[] =
661 ADD_TABLE(ci2_component),
662 ADD_TABLE(directory),
663 ADD_TABLE(rof_feature),
664 ADD_TABLE(ci2_feature_comp),
665 ADD_TABLE(ci2_file),
666 ADD_TABLE(install_exec_seq),
667 ADD_TABLE(rof_media),
668 ADD_TABLE(property),
671 static const msi_table spf_tables[] =
673 ADD_TABLE(ci_component),
674 ADD_TABLE(directory),
675 ADD_TABLE(rof_feature),
676 ADD_TABLE(rof_feature_comp),
677 ADD_TABLE(rof_file),
678 ADD_TABLE(spf_install_exec_seq),
679 ADD_TABLE(rof_media),
680 ADD_TABLE(property),
681 ADD_TABLE(spf_custom_action),
682 ADD_TABLE(spf_install_ui_seq),
685 static const msi_table pp_tables[] =
687 ADD_TABLE(ci_component),
688 ADD_TABLE(directory),
689 ADD_TABLE(rof_feature),
690 ADD_TABLE(rof_feature_comp),
691 ADD_TABLE(rof_file),
692 ADD_TABLE(pp_install_exec_seq),
693 ADD_TABLE(rof_media),
694 ADD_TABLE(property),
697 static const msi_table tp_tables[] =
699 ADD_TABLE(tp_component),
700 ADD_TABLE(directory),
701 ADD_TABLE(rof_feature),
702 ADD_TABLE(ci2_feature_comp),
703 ADD_TABLE(ci2_file),
704 ADD_TABLE(install_exec_seq),
705 ADD_TABLE(rof_media),
706 ADD_TABLE(property),
709 static const msi_table cwd_tables[] =
711 ADD_TABLE(cwd_component),
712 ADD_TABLE(directory),
713 ADD_TABLE(rof_feature),
714 ADD_TABLE(ci2_feature_comp),
715 ADD_TABLE(ci2_file),
716 ADD_TABLE(install_exec_seq),
717 ADD_TABLE(rof_media),
718 ADD_TABLE(property),
721 static const msi_table adm_tables[] =
723 ADD_TABLE(adm_component),
724 ADD_TABLE(directory),
725 ADD_TABLE(rof_feature),
726 ADD_TABLE(ci2_feature_comp),
727 ADD_TABLE(ci2_file),
728 ADD_TABLE(install_exec_seq),
729 ADD_TABLE(rof_media),
730 ADD_TABLE(property),
731 ADD_TABLE(adm_custom_action),
732 ADD_TABLE(adm_admin_exec_seq),
735 static const msi_table amp_tables[] =
737 ADD_TABLE(amp_component),
738 ADD_TABLE(directory),
739 ADD_TABLE(rof_feature),
740 ADD_TABLE(ci2_feature_comp),
741 ADD_TABLE(ci2_file),
742 ADD_TABLE(install_exec_seq),
743 ADD_TABLE(rof_media),
744 ADD_TABLE(property),
747 static const msi_table rem_tables[] =
749 ADD_TABLE(rem_component),
750 ADD_TABLE(directory),
751 ADD_TABLE(rof_feature),
752 ADD_TABLE(rem_feature_comp),
753 ADD_TABLE(rem_file),
754 ADD_TABLE(rem_install_exec_seq),
755 ADD_TABLE(rof_media),
756 ADD_TABLE(property),
757 ADD_TABLE(rem_remove_files),
760 /* cabinet definitions */
762 /* make the max size large so there is only one cab file */
763 #define MEDIA_SIZE 0x7FFFFFFF
764 #define FOLDER_THRESHOLD 900000
766 /* the FCI callbacks */
768 static void *mem_alloc(ULONG cb)
770 return HeapAlloc(GetProcessHeap(), 0, cb);
773 static void mem_free(void *memory)
775 HeapFree(GetProcessHeap(), 0, memory);
778 static BOOL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
780 sprintf(pccab->szCab, pv, pccab->iCab);
781 return TRUE;
784 static long progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
786 return 0;
789 static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
790 BOOL fContinuation, void *pv)
792 return 0;
795 static INT_PTR fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
797 HANDLE handle;
798 DWORD dwAccess = 0;
799 DWORD dwShareMode = 0;
800 DWORD dwCreateDisposition = OPEN_EXISTING;
802 dwAccess = GENERIC_READ | GENERIC_WRITE;
803 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
804 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
806 if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
807 dwCreateDisposition = OPEN_EXISTING;
808 else
809 dwCreateDisposition = CREATE_NEW;
811 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
812 dwCreateDisposition, 0, NULL);
814 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
816 return (INT_PTR)handle;
819 static UINT fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
821 HANDLE handle = (HANDLE)hf;
822 DWORD dwRead;
823 BOOL res;
825 res = ReadFile(handle, memory, cb, &dwRead, NULL);
826 ok(res, "Failed to ReadFile\n");
828 return dwRead;
831 static UINT fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
833 HANDLE handle = (HANDLE)hf;
834 DWORD dwWritten;
835 BOOL res;
837 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
838 ok(res, "Failed to WriteFile\n");
840 return dwWritten;
843 static int fci_close(INT_PTR hf, int *err, void *pv)
845 HANDLE handle = (HANDLE)hf;
846 ok(CloseHandle(handle), "Failed to CloseHandle\n");
848 return 0;
851 static long fci_seek(INT_PTR hf, long dist, int seektype, int *err, void *pv)
853 HANDLE handle = (HANDLE)hf;
854 DWORD ret;
856 ret = SetFilePointer(handle, dist, NULL, seektype);
857 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
859 return ret;
862 static int fci_delete(char *pszFile, int *err, void *pv)
864 BOOL ret = DeleteFileA(pszFile);
865 ok(ret, "Failed to DeleteFile %s\n", pszFile);
867 return 0;
870 static void init_functionpointers(void)
872 HMODULE hmsi = GetModuleHandleA("msi.dll");
874 #define GET_PROC(func) \
875 p ## func = (void*)GetProcAddress(hmsi, #func); \
876 if(!p ## func) \
877 trace("GetProcAddress(%s) failed\n", #func);
879 GET_PROC(MsiQueryComponentStateA);
880 GET_PROC(MsiSourceListGetInfoA);
882 #undef GET_PROC
885 static BOOL check_record(MSIHANDLE rec, UINT field, LPCSTR val)
887 CHAR buffer[0x20];
888 UINT r;
889 DWORD sz;
891 sz = sizeof buffer;
892 r = MsiRecordGetString(rec, field, buffer, &sz);
893 return (r == ERROR_SUCCESS ) && !strcmp(val, buffer);
896 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
898 LPSTR tempname;
900 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
901 GetTempFileNameA(".", "xx", 0, tempname);
903 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
905 lstrcpyA(pszTempName, tempname);
906 HeapFree(GetProcessHeap(), 0, tempname);
907 return TRUE;
910 HeapFree(GetProcessHeap(), 0, tempname);
912 return FALSE;
915 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
916 USHORT *pattribs, int *err, void *pv)
918 BY_HANDLE_FILE_INFORMATION finfo;
919 FILETIME filetime;
920 HANDLE handle;
921 DWORD attrs;
922 BOOL res;
924 handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
925 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
927 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
929 res = GetFileInformationByHandle(handle, &finfo);
930 ok(res, "Expected GetFileInformationByHandle to succeed\n");
932 FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
933 FileTimeToDosDateTime(&filetime, pdate, ptime);
935 attrs = GetFileAttributes(pszName);
936 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
938 return (INT_PTR)handle;
941 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
943 char path[MAX_PATH];
944 char filename[MAX_PATH];
946 lstrcpyA(path, CURR_DIR);
947 lstrcatA(path, "\\");
948 lstrcatA(path, file);
950 lstrcpyA(filename, file);
952 return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
953 progress, get_open_info, compress);
956 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
958 ZeroMemory(pCabParams, sizeof(CCAB));
960 pCabParams->cb = max_size;
961 pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
962 pCabParams->setID = 0xbeef;
963 pCabParams->iCab = 1;
964 lstrcpyA(pCabParams->szCabPath, CURR_DIR);
965 lstrcatA(pCabParams->szCabPath, "\\");
966 lstrcpyA(pCabParams->szCab, name);
969 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
971 CCAB cabParams;
972 LPCSTR ptr;
973 HFCI hfci;
974 ERF erf;
975 BOOL res;
977 set_cab_parameters(&cabParams, name, max_size);
979 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
980 fci_read, fci_write, fci_close, fci_seek, fci_delete,
981 get_temp_file, &cabParams, NULL);
983 ok(hfci != NULL, "Failed to create an FCI context\n");
985 ptr = files;
986 while (*ptr)
988 res = add_file(hfci, ptr, tcompTYPE_MSZIP);
989 ok(res, "Failed to add file: %s\n", ptr);
990 ptr += lstrlen(ptr) + 1;
993 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
994 ok(res, "Failed to flush the cabinet\n");
996 res = FCIDestroy(hfci);
997 ok(res, "Failed to destroy the cabinet\n");
1000 static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
1002 HKEY hkey;
1003 DWORD type, size;
1005 if (RegOpenKey(HKEY_LOCAL_MACHINE,
1006 "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
1007 return FALSE;
1009 size = MAX_PATH;
1010 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
1011 RegCloseKey(hkey);
1012 return FALSE;
1015 size = MAX_PATH;
1016 if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
1017 RegCloseKey(hkey);
1018 return FALSE;
1021 RegCloseKey(hkey);
1022 return TRUE;
1025 static void create_file(const CHAR *name, DWORD size)
1027 HANDLE file;
1028 DWORD written, left;
1030 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1031 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1032 WriteFile(file, name, strlen(name), &written, NULL);
1033 WriteFile(file, "\n", strlen("\n"), &written, NULL);
1035 left = size - lstrlen(name) - 1;
1037 SetFilePointer(file, left, NULL, FILE_CURRENT);
1038 SetEndOfFile(file);
1040 CloseHandle(file);
1043 static void create_test_files(void)
1045 CreateDirectoryA("msitest", NULL);
1046 create_file("msitest\\one.txt", 100);
1047 CreateDirectoryA("msitest\\first", NULL);
1048 create_file("msitest\\first\\two.txt", 100);
1049 CreateDirectoryA("msitest\\second", NULL);
1050 create_file("msitest\\second\\three.txt", 100);
1052 create_file("four.txt", 100);
1053 create_file("five.txt", 100);
1054 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1056 create_file("msitest\\filename", 100);
1057 create_file("msitest\\service.exe", 100);
1059 DeleteFileA("four.txt");
1060 DeleteFileA("five.txt");
1063 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
1065 CHAR path[MAX_PATH];
1067 lstrcpyA(path, PROG_FILES_DIR);
1068 lstrcatA(path, "\\");
1069 lstrcatA(path, rel_path);
1071 if (is_file)
1072 return DeleteFileA(path);
1073 else
1074 return RemoveDirectoryA(path);
1077 static BOOL delete_cf(const CHAR *rel_path, BOOL is_file)
1079 CHAR path[MAX_PATH];
1081 lstrcpyA(path, COMMON_FILES_DIR);
1082 lstrcatA(path, "\\");
1083 lstrcatA(path, rel_path);
1085 if (is_file)
1086 return DeleteFileA(path);
1087 else
1088 return RemoveDirectoryA(path);
1091 static void delete_test_files(void)
1093 DeleteFileA("msitest.msi");
1094 DeleteFileA("msitest.cab");
1095 DeleteFileA("msitest\\second\\three.txt");
1096 DeleteFileA("msitest\\first\\two.txt");
1097 DeleteFileA("msitest\\one.txt");
1098 DeleteFileA("msitest\\service.exe");
1099 DeleteFileA("msitest\\filename");
1100 RemoveDirectoryA("msitest\\second");
1101 RemoveDirectoryA("msitest\\first");
1102 RemoveDirectoryA("msitest");
1105 static void write_file(const CHAR *filename, const char *data, int data_size)
1107 DWORD size;
1109 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
1110 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1112 WriteFile(hf, data, data_size, &size, NULL);
1113 CloseHandle(hf);
1116 static void write_msi_summary_info(MSIHANDLE db)
1118 MSIHANDLE summary;
1119 UINT r;
1121 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1124 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, ";1033");
1125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1127 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1128 "{004757CA-5092-49c2-AD20-28E1CE0DF5F2}");
1129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1131 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
1132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1134 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 0, NULL, NULL);
1135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1137 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1138 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1140 /* write the summary changes back to the stream */
1141 r = MsiSummaryInfoPersist(summary);
1142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1144 MsiCloseHandle(summary);
1147 static void create_database(const CHAR *name, const msi_table *tables, int num_tables)
1149 MSIHANDLE db;
1150 UINT r;
1151 int j;
1153 r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1154 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1156 /* import the tables into the database */
1157 for (j = 0; j < num_tables; j++)
1159 const msi_table *table = &tables[j];
1161 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1163 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1166 DeleteFileA(table->filename);
1169 write_msi_summary_info(db);
1171 r = MsiDatabaseCommit(db);
1172 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1174 MsiCloseHandle(db);
1177 static void check_service_is_installed(void)
1179 SC_HANDLE scm, service;
1180 BOOL res;
1182 scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1183 ok(scm != NULL, "Failed to open the SC Manager\n");
1185 service = OpenService(scm, "TestService", SC_MANAGER_ALL_ACCESS);
1186 ok(service != NULL, "Failed to open TestService\n");
1188 res = DeleteService(service);
1189 ok(res, "Failed to delete TestService\n");
1192 static void test_MsiInstallProduct(void)
1194 UINT r;
1195 CHAR path[MAX_PATH];
1196 LONG res;
1197 HKEY hkey;
1198 DWORD num, size, type;
1200 create_test_files();
1201 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1203 r = MsiInstallProductA(msifile, NULL);
1204 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1206 ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
1207 ok(delete_pf("msitest\\cabout\\new", FALSE), "File not installed\n");
1208 ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
1209 ok(delete_pf("msitest\\cabout", FALSE), "File not installed\n");
1210 ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
1211 ok(delete_pf("msitest\\changed", FALSE), "File not installed\n");
1212 ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
1213 ok(delete_pf("msitest\\first", FALSE), "File not installed\n");
1214 ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
1215 ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
1216 ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
1217 ok(delete_pf("msitest", FALSE), "File not installed\n");
1219 res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
1220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1222 size = MAX_PATH;
1223 type = REG_SZ;
1224 res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
1225 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1226 ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
1228 size = MAX_PATH;
1229 type = REG_SZ;
1230 res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
1231 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
1233 size = sizeof(num);
1234 type = REG_DWORD;
1235 res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
1236 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1237 ok(num == 314, "Expected 314, got %d\n", num);
1239 size = MAX_PATH;
1240 type = REG_SZ;
1241 res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
1242 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1243 ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
1245 check_service_is_installed();
1247 RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
1249 delete_test_files();
1252 static void test_MsiSetComponentState(void)
1254 INSTALLSTATE installed, action;
1255 MSIHANDLE package;
1256 char path[MAX_PATH];
1257 UINT r;
1259 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1261 CoInitialize(NULL);
1263 lstrcpy(path, CURR_DIR);
1264 lstrcat(path, "\\");
1265 lstrcat(path, msifile);
1267 r = MsiOpenPackage(path, &package);
1268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1270 r = MsiDoAction(package, "CostInitialize");
1271 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1273 r = MsiDoAction(package, "FileCost");
1274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1276 r = MsiDoAction(package, "CostFinalize");
1277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1279 r = MsiGetComponentState(package, "dangler", &installed, &action);
1280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1281 ok(installed == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", installed);
1282 ok(action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1284 r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
1285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1287 MsiCloseHandle(package);
1288 CoUninitialize();
1290 DeleteFileA(msifile);
1293 static void test_packagecoltypes(void)
1295 MSIHANDLE hdb, view, rec;
1296 char path[MAX_PATH];
1297 LPCSTR query;
1298 UINT r, count;
1300 create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
1302 CoInitialize(NULL);
1304 lstrcpy(path, CURR_DIR);
1305 lstrcat(path, "\\");
1306 lstrcat(path, msifile);
1308 r = MsiOpenDatabase(path, MSIDBOPEN_READONLY, &hdb);
1309 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1311 query = "SELECT * FROM `Media`";
1312 r = MsiDatabaseOpenView( hdb, query, &view );
1313 ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
1315 r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
1316 count = MsiRecordGetFieldCount( rec );
1317 ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1318 ok(count == 6, "Expected 6, got %d\n", count);
1319 ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
1320 ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
1321 ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
1322 ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
1323 ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
1324 ok(check_record(rec, 6, "Source"), "wrong column label\n");
1325 MsiCloseHandle(rec);
1327 r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
1328 count = MsiRecordGetFieldCount( rec );
1329 ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
1330 ok(count == 6, "Expected 6, got %d\n", count);
1331 ok(check_record(rec, 1, "i2"), "wrong column label\n");
1332 ok(check_record(rec, 2, "i4"), "wrong column label\n");
1333 ok(check_record(rec, 3, "L64"), "wrong column label\n");
1334 ok(check_record(rec, 4, "S255"), "wrong column label\n");
1335 ok(check_record(rec, 5, "S32"), "wrong column label\n");
1336 ok(check_record(rec, 6, "S72"), "wrong column label\n");
1338 MsiCloseHandle(rec);
1339 MsiCloseHandle(view);
1340 MsiCloseHandle(hdb);
1341 DeleteFile(msifile);
1344 static void create_cc_test_files(void)
1346 CCAB cabParams;
1347 HFCI hfci;
1348 ERF erf;
1349 static CHAR cab_context[] = "test%d.cab";
1350 BOOL res;
1352 create_file("maximus", 500);
1353 create_file("augustus", 50000);
1354 create_file("caesar", 500);
1356 set_cab_parameters(&cabParams, "test1.cab", 200);
1358 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
1359 fci_read, fci_write, fci_close, fci_seek, fci_delete,
1360 get_temp_file, &cabParams, cab_context);
1361 ok(hfci != NULL, "Failed to create an FCI context\n");
1363 res = add_file(hfci, "maximus", tcompTYPE_MSZIP);
1364 ok(res, "Failed to add file maximus\n");
1366 res = add_file(hfci, "augustus", tcompTYPE_MSZIP);
1367 ok(res, "Failed to add file augustus\n");
1369 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
1370 ok(res, "Failed to flush the cabinet\n");
1372 res = FCIDestroy(hfci);
1373 ok(res, "Failed to destroy the cabinet\n");
1375 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1377 DeleteFile("maximus");
1378 DeleteFile("augustus");
1379 DeleteFile("caesar");
1382 static void delete_cab_files(void)
1384 SHFILEOPSTRUCT shfl;
1385 CHAR path[MAX_PATH+10];
1387 lstrcpyA(path, CURR_DIR);
1388 lstrcatA(path, "\\*.cab");
1389 path[strlen(path) + 1] = '\0';
1391 shfl.hwnd = NULL;
1392 shfl.wFunc = FO_DELETE;
1393 shfl.pFrom = path;
1394 shfl.pTo = NULL;
1395 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1397 SHFileOperation(&shfl);
1400 static void test_continuouscabs(void)
1402 UINT r;
1404 create_cc_test_files();
1405 create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1407 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1409 r = MsiInstallProductA(msifile, NULL);
1410 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1411 todo_wine
1413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1414 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1415 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1417 ok(delete_pf("msitest", FALSE), "File not installed\n");
1419 delete_cab_files();
1420 DeleteFile(msifile);
1423 static void test_caborder(void)
1425 UINT r;
1427 create_file("imperator", 100);
1428 create_file("maximus", 500);
1429 create_file("augustus", 50000);
1430 create_file("caesar", 500);
1432 create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
1434 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1436 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1437 create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1438 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1440 r = MsiInstallProductA(msifile, NULL);
1441 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1442 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1443 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1444 todo_wine
1446 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1447 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1450 delete_cab_files();
1452 create_cab_file("test1.cab", MEDIA_SIZE, "imperator\0");
1453 create_cab_file("test2.cab", MEDIA_SIZE, "maximus\0augustus\0");
1454 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1456 r = MsiInstallProductA(msifile, NULL);
1457 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1458 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1459 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1460 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1461 todo_wine
1463 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1466 delete_cab_files();
1467 DeleteFile(msifile);
1469 create_cc_test_files();
1470 create_database(msifile, co_tables, sizeof(co_tables) / sizeof(msi_table));
1472 r = MsiInstallProductA(msifile, NULL);
1473 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1474 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1475 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1476 todo_wine
1478 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1479 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1482 delete_cab_files();
1483 DeleteFile(msifile);
1485 create_cc_test_files();
1486 create_database(msifile, co2_tables, sizeof(co2_tables) / sizeof(msi_table));
1488 r = MsiInstallProductA(msifile, NULL);
1489 ok(!delete_pf("msitest\\augustus", TRUE), "File is installed\n");
1490 ok(!delete_pf("msitest\\caesar", TRUE), "File is installed\n");
1491 todo_wine
1493 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
1494 ok(!delete_pf("msitest\\maximus", TRUE), "File is installed\n");
1495 ok(!delete_pf("msitest", FALSE), "File is installed\n");
1498 delete_cab_files();
1499 DeleteFile("imperator");
1500 DeleteFile("maximus");
1501 DeleteFile("augustus");
1502 DeleteFile("caesar");
1503 DeleteFile(msifile);
1506 static void test_mixedmedia(void)
1508 UINT r;
1510 CreateDirectoryA("msitest", NULL);
1511 create_file("msitest\\maximus", 500);
1512 create_file("msitest\\augustus", 500);
1513 create_file("caesar", 500);
1515 create_database(msifile, mm_tables, sizeof(mm_tables) / sizeof(msi_table));
1517 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1519 create_cab_file("test1.cab", MEDIA_SIZE, "caesar\0");
1521 r = MsiInstallProductA(msifile, NULL);
1522 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1523 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1524 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1525 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1526 ok(delete_pf("msitest", FALSE), "File not installed\n");
1528 /* Delete the files in the temp (current) folder */
1529 DeleteFile("msitest\\maximus");
1530 DeleteFile("msitest\\augustus");
1531 RemoveDirectory("msitest");
1532 DeleteFile("caesar");
1533 DeleteFile("test1.cab");
1534 DeleteFile(msifile);
1537 static void test_samesequence(void)
1539 UINT r;
1541 create_cc_test_files();
1542 create_database(msifile, ss_tables, sizeof(ss_tables) / sizeof(msi_table));
1544 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1546 r = MsiInstallProductA(msifile, NULL);
1547 todo_wine
1549 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1550 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1551 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1553 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1554 ok(delete_pf("msitest", FALSE), "File not installed\n");
1556 delete_cab_files();
1557 DeleteFile(msifile);
1560 static void test_uiLevelFlags(void)
1562 UINT r;
1564 create_cc_test_files();
1565 create_database(msifile, ui_tables, sizeof(ui_tables) / sizeof(msi_table));
1567 MsiSetInternalUI(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY, NULL);
1569 r = MsiInstallProductA(msifile, NULL);
1570 ok(!delete_pf("msitest\\maximus", TRUE), "UI install occurred, but execute-only was requested.\n");
1571 todo_wine
1573 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1574 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1576 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1577 ok(delete_pf("msitest", FALSE), "File not installed\n");
1579 delete_cab_files();
1580 DeleteFile(msifile);
1583 static BOOL file_matches(LPSTR path)
1585 CHAR buf[MAX_PATH];
1586 HANDLE file;
1587 DWORD size;
1589 file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1590 NULL, OPEN_EXISTING, 0, NULL);
1592 ZeroMemory(buf, MAX_PATH);
1593 ReadFile(file, buf, 15, &size, NULL);
1594 CloseHandle(file);
1596 return !lstrcmp(buf, "msitest\\maximus");
1599 static void test_readonlyfile(void)
1601 UINT r;
1602 DWORD size;
1603 HANDLE file;
1604 CHAR path[MAX_PATH];
1606 CreateDirectoryA("msitest", NULL);
1607 create_file("msitest\\maximus", 500);
1608 create_database(msifile, rof_tables, sizeof(rof_tables) / sizeof(msi_table));
1610 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1612 lstrcpy(path, PROG_FILES_DIR);
1613 lstrcat(path, "\\msitest");
1614 CreateDirectory(path, NULL);
1616 lstrcat(path, "\\maximus");
1617 file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1618 NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
1620 WriteFile(file, "readonlyfile", 20, &size, NULL);
1621 CloseHandle(file);
1623 r = MsiInstallProductA(msifile, NULL);
1624 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1625 ok(file_matches(path), "Expected file to be overwritten\n");
1626 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1627 ok(delete_pf("msitest", FALSE), "File not installed\n");
1629 /* Delete the files in the temp (current) folder */
1630 DeleteFile("msitest\\maximus");
1631 RemoveDirectory("msitest");
1632 DeleteFile(msifile);
1635 static void test_setdirproperty(void)
1637 UINT r;
1639 CreateDirectoryA("msitest", NULL);
1640 create_file("msitest\\maximus", 500);
1641 create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table));
1643 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1645 r = MsiInstallProductA(msifile, NULL);
1646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1647 ok(delete_cf("msitest\\maximus", TRUE), "File not installed\n");
1648 ok(delete_cf("msitest", FALSE), "File not installed\n");
1650 /* Delete the files in the temp (current) folder */
1651 DeleteFile(msifile);
1652 DeleteFile("msitest\\maximus");
1653 RemoveDirectory("msitest");
1656 static void test_cabisextracted(void)
1658 UINT r;
1660 CreateDirectoryA("msitest", NULL);
1661 create_file("msitest\\gaius", 500);
1662 create_file("maximus", 500);
1663 create_file("augustus", 500);
1664 create_file("caesar", 500);
1666 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
1667 create_cab_file("test2.cab", MEDIA_SIZE, "augustus\0");
1668 create_cab_file("test3.cab", MEDIA_SIZE, "caesar\0");
1670 create_database(msifile, cie_tables, sizeof(cie_tables) / sizeof(msi_table));
1672 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
1674 r = MsiInstallProductA(msifile, NULL);
1675 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1676 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1677 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1678 ok(delete_pf("msitest\\caesar", TRUE), "File not installed\n");
1679 ok(delete_pf("msitest\\gaius", TRUE), "File not installed\n");
1680 ok(delete_pf("msitest", FALSE), "File not installed\n");
1682 /* Delete the files in the temp (current) folder */
1683 delete_cab_files();
1684 DeleteFile(msifile);
1685 DeleteFile("maximus");
1686 DeleteFile("augustus");
1687 DeleteFile("caesar");
1688 DeleteFile("msitest\\gaius");
1689 RemoveDirectory("msitest");
1692 static void test_concurrentinstall(void)
1694 UINT r;
1695 CHAR path[MAX_PATH];
1697 CreateDirectoryA("msitest", NULL);
1698 CreateDirectoryA("msitest\\msitest", NULL);
1699 create_file("msitest\\maximus", 500);
1700 create_file("msitest\\msitest\\augustus", 500);
1702 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
1704 lstrcpyA(path, CURR_DIR);
1705 lstrcatA(path, "\\msitest\\concurrent.msi");
1706 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
1708 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1710 r = MsiInstallProductA(msifile, NULL);
1711 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1712 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
1713 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
1714 ok(delete_pf("msitest", FALSE), "File not installed\n");
1716 /* Delete the files in the temp (current) folder */
1717 DeleteFile(msifile);
1718 DeleteFile(path);
1719 DeleteFile("msitest\\msitest\\augustus");
1720 DeleteFile("msitest\\maximus");
1721 RemoveDirectory("msitest\\msitest");
1722 RemoveDirectory("msitest");
1725 static void test_setpropertyfolder(void)
1727 UINT r;
1729 CreateDirectoryA("msitest", NULL);
1730 create_file("msitest\\maximus", 500);
1732 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
1734 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1736 r = MsiInstallProductA(msifile, NULL);
1737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1738 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
1739 ok(delete_pf("msitest\\added", FALSE), "File not installed\n");
1740 ok(delete_pf("msitest", FALSE), "File not installed\n");
1742 /* Delete the files in the temp (current) folder */
1743 DeleteFile(msifile);
1744 DeleteFile("msitest\\maximus");
1745 RemoveDirectory("msitest");
1748 static BOOL file_exists(LPCSTR file)
1750 return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
1753 static BOOL pf_exists(LPCSTR file)
1755 CHAR path[MAX_PATH];
1757 lstrcpyA(path, PROG_FILES_DIR);
1758 lstrcatA(path, "\\");
1759 lstrcatA(path, file);
1761 return file_exists(path);
1764 static void delete_pfmsitest_files(void)
1766 SHFILEOPSTRUCT shfl;
1767 CHAR path[MAX_PATH+11];
1769 lstrcpyA(path, PROG_FILES_DIR);
1770 lstrcatA(path, "\\msitest\\*");
1771 path[strlen(path) + 1] = '\0';
1773 shfl.hwnd = NULL;
1774 shfl.wFunc = FO_DELETE;
1775 shfl.pFrom = path;
1776 shfl.pTo = NULL;
1777 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
1779 SHFileOperation(&shfl);
1781 lstrcpyA(path, PROG_FILES_DIR);
1782 lstrcatA(path, "\\msitest");
1783 RemoveDirectoryA(path);
1786 static void test_publish(void)
1788 UINT r;
1789 INSTALLSTATE state;
1790 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
1792 CreateDirectoryA("msitest", NULL);
1793 create_file("msitest\\maximus", 500);
1795 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
1797 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
1799 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1800 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1802 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1803 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1805 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1806 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1808 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1809 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1810 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1811 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1813 /* nothing published */
1814 r = MsiInstallProductA(msifile, NULL);
1815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1816 ok(pf_exists("msitest\\maximus"), "File not installed\n");
1817 ok(pf_exists("msitest"), "File not installed\n");
1819 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1820 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1822 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1823 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1825 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1826 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1828 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1829 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1830 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1831 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1833 /* install again */
1834 r = MsiInstallProductA(msifile, NULL);
1835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1836 ok(pf_exists("msitest\\maximus"), "File not installed\n");
1837 ok(pf_exists("msitest"), "File not installed\n");
1839 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1840 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1842 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1843 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1845 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1846 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1848 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1849 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1850 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1851 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1853 /* try to uninstall */
1854 r = MsiInstallProductA(msifile, "REMOVE=ALL");
1855 todo_wine
1857 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1859 ok(pf_exists("msitest\\maximus"), "File deleted\n");
1860 ok(pf_exists("msitest"), "File deleted\n");
1862 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1863 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1865 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1866 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1868 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1869 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1871 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1872 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1873 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1874 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1876 /* PublishProduct */
1877 r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
1878 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1879 ok(pf_exists("msitest\\maximus"), "File not installed\n");
1880 ok(pf_exists("msitest"), "File not installed\n");
1882 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1883 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1885 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1886 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1888 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1889 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1890 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1891 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1893 /* try to uninstall after PublishProduct */
1894 r = MsiInstallProductA(msifile, "REMOVE=ALL");
1895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1896 ok(pf_exists("msitest\\maximus"), "File deleted\n");
1897 ok(pf_exists("msitest"), "File deleted\n");
1899 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1900 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1902 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1903 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1905 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1906 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1908 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1909 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1910 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1911 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1913 /* PublishProduct and RegisterProduct */
1914 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
1915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1916 ok(pf_exists("msitest\\maximus"), "File not installed\n");
1917 ok(pf_exists("msitest"), "File not installed\n");
1919 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1920 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1922 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1923 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1925 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1926 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1928 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1929 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1930 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1931 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1933 /* try it again */
1934 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
1935 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1936 ok(pf_exists("msitest\\maximus"), "File not installed\n");
1937 ok(pf_exists("msitest"), "File not installed\n");
1939 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1940 todo_wine
1942 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1945 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1946 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1948 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1949 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1951 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1952 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1953 todo_wine
1955 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1957 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1959 /* uninstall has a problem with this */
1960 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
1961 todo_wine
1963 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1965 ok(pf_exists("msitest\\maximus"), "File deleted\n");
1966 ok(pf_exists("msitest"), "File deleted\n");
1968 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1969 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1971 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1972 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1974 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1975 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1976 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1977 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1979 /* PublishProduct and RegisterProduct and ProcessComponents */
1980 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1");
1981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1982 ok(pf_exists("msitest\\maximus"), "File not installed\n");
1983 ok(pf_exists("msitest"), "File not installed\n");
1985 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
1986 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1988 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
1989 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1991 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
1992 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1994 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1995 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
1996 todo_wine
1998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1999 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2002 /* complete uninstall */
2003 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2005 ok(pf_exists("msitest\\maximus"), "File deleted\n");
2006 ok(pf_exists("msitest"), "File deleted\n");
2008 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2009 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2011 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2012 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2014 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2015 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2017 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2018 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2019 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2020 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2022 /* PublishProduct, RegisterProduct, ProcessComponents, PublishFeatures */
2023 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1 PUBLISH_FEATURES=1");
2024 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2025 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2026 ok(pf_exists("msitest"), "File not installed\n");
2028 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2029 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2031 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2032 todo_wine
2034 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2037 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2038 todo_wine
2040 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2043 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2044 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2045 todo_wine
2047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2048 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2051 /* complete uninstall */
2052 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2053 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2054 todo_wine
2056 ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2057 ok(!pf_exists("msitest"), "File deleted\n");
2060 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2061 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2063 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");\
2064 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2066 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2067 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2069 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2070 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2071 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2072 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2074 /* complete install */
2075 r = MsiInstallProductA(msifile, "FULL=1");
2076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2077 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2078 ok(pf_exists("msitest"), "File not installed\n");
2080 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2081 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2083 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2084 todo_wine
2086 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2089 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2090 todo_wine
2092 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2095 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2096 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2097 todo_wine
2099 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2100 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2103 /* no UnpublishFeatures */
2104 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2106 todo_wine
2108 ok(!pf_exists("msitest\\maximus"), "File deleted\n");
2109 ok(!pf_exists("msitest"), "File deleted\n");
2112 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2113 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2115 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2116 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2118 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2119 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2121 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2122 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2123 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2124 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2126 /* complete install */
2127 r = MsiInstallProductA(msifile, "FULL=1");
2128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2129 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2130 ok(pf_exists("msitest"), "File not installed\n");
2132 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2133 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2135 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2136 todo_wine
2138 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2141 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2142 todo_wine
2144 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2147 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2148 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2149 todo_wine
2151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2152 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2155 /* UnpublishFeatures, only feature removed. Only works when entire product is removed */
2156 r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
2157 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2158 ok(pf_exists("msitest\\maximus"), "File deleted\n");
2159 ok(pf_exists("msitest"), "File deleted\n");
2161 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2162 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2164 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2165 todo_wine
2167 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2170 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2171 todo_wine
2173 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2176 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2177 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2178 todo_wine
2180 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2181 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2184 /* complete install */
2185 r = MsiInstallProductA(msifile, "FULL=1");
2186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2187 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2188 ok(pf_exists("msitest"), "File not installed\n");
2190 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2191 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2193 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2194 todo_wine
2196 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2199 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2200 todo_wine
2202 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2205 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2206 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2207 todo_wine
2209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2210 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2213 /* UnpublishFeatures, both features removed */
2214 r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
2215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2216 todo_wine
2218 ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2219 ok(!pf_exists("msitest"), "File not deleted\n");
2222 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2223 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2225 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2226 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2228 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2229 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2231 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2232 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2233 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2234 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2236 /* complete install */
2237 r = MsiInstallProductA(msifile, "FULL=1");
2238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2239 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2240 ok(pf_exists("msitest"), "File not installed\n");
2242 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2243 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
2245 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2246 todo_wine
2248 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2251 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2252 todo_wine
2254 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2257 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2258 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2259 todo_wine
2261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2262 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2265 /* complete uninstall */
2266 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2268 todo_wine
2270 ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2271 ok(!pf_exists("msitest"), "File not deleted\n");
2274 state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2275 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2277 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
2278 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2280 state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
2281 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2283 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2284 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
2285 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2286 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2288 /* make sure 'Program Files\msitest' is removed */
2289 delete_pfmsitest_files();
2291 DeleteFile(msifile);
2292 DeleteFile("msitest\\maximus");
2293 RemoveDirectory("msitest");
2296 static void test_publishsourcelist(void)
2298 UINT r;
2299 DWORD size;
2300 CHAR value[MAX_PATH];
2301 CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2303 CreateDirectoryA("msitest", NULL);
2304 create_file("msitest\\maximus", 500);
2306 create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2308 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2310 r = MsiInstallProductA(msifile, NULL);
2311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2312 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2313 ok(pf_exists("msitest"), "File not installed\n");
2315 /* nothing published */
2316 size = 0xdeadbeef;
2317 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2318 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2319 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2320 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2322 r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2324 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2325 ok(pf_exists("msitest"), "File not installed\n");
2327 /* after RegisterProduct */
2328 size = 0xdeadbeef;
2329 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2330 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2331 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2332 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2334 r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
2335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2336 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2337 ok(pf_exists("msitest"), "File not installed\n");
2339 /* after ProcessComponents */
2340 size = 0xdeadbeef;
2341 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2342 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2343 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2344 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2346 r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
2347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2348 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2349 ok(pf_exists("msitest"), "File not installed\n");
2351 /* after PublishFeatures */
2352 size = 0xdeadbeef;
2353 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2354 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
2355 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2356 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
2358 r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2360 ok(pf_exists("msitest\\maximus"), "File not installed\n");
2361 ok(pf_exists("msitest"), "File not installed\n");
2363 /* after PublishProduct */
2364 size = MAX_PATH;
2365 lstrcpyA(value, "aaa");
2366 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2367 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
2368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2369 ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
2370 ok(size == 11, "Expected 11, got %d\n", size);
2372 /* complete uninstall */
2373 r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
2374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2375 todo_wine
2377 ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
2378 ok(!pf_exists("msitest"), "File not deleted\n");
2381 /* make sure 'Program Files\msitest' is removed */
2382 delete_pfmsitest_files();
2384 DeleteFile(msifile);
2385 DeleteFile("msitest\\maximus");
2386 RemoveDirectory("msitest");
2389 static UINT run_query(MSIHANDLE hdb, MSIHANDLE hrec, const char *query)
2391 MSIHANDLE hview = 0;
2392 UINT r;
2394 r = MsiDatabaseOpenView(hdb, query, &hview);
2395 if(r != ERROR_SUCCESS)
2396 return r;
2398 r = MsiViewExecute(hview, hrec);
2399 if(r == ERROR_SUCCESS)
2400 r = MsiViewClose(hview);
2401 MsiCloseHandle(hview);
2402 return r;
2405 static void set_transform_summary_info(void)
2407 UINT r;
2408 MSIHANDLE suminfo;
2410 /* build summmary info */
2411 r = MsiGetSummaryInformation(0, mstfile, 3, &suminfo);
2412 todo_wine
2414 ok(r == ERROR_SUCCESS , "Failed to open summaryinfo\n");
2417 r = MsiSummaryInfoSetProperty(suminfo, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2418 todo_wine
2420 ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2423 r = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2424 "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2425 "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}1.1.1;"
2426 "{4C0EAA15-0264-4E5A-8758-609EF142B92D}");
2427 todo_wine
2429 ok(r == ERROR_SUCCESS , "Failed to set summary info\n");
2432 r = MsiSummaryInfoSetProperty(suminfo, PID_PAGECOUNT, VT_I4, 100, NULL, NULL);
2433 todo_wine
2435 ok(r == ERROR_SUCCESS, "Failed to set summary info\n");
2438 r = MsiSummaryInfoPersist(suminfo);
2439 todo_wine
2441 ok(r == ERROR_SUCCESS , "Failed to make summary info persist\n");
2444 r = MsiCloseHandle(suminfo);
2445 todo_wine
2447 ok(r == ERROR_SUCCESS , "Failed to close suminfo\n");
2451 static void generate_transform(void)
2453 MSIHANDLE hdb1, hdb2;
2454 LPCSTR query;
2455 UINT r;
2457 /* start with two identical databases */
2458 CopyFile(msifile, msifile2, FALSE);
2460 r = MsiOpenDatabase(msifile2, MSIDBOPEN_TRANSACT, &hdb1);
2461 ok(r == ERROR_SUCCESS , "Failed to create database\n");
2463 r = MsiDatabaseCommit(hdb1);
2464 ok(r == ERROR_SUCCESS , "Failed to commit database\n");
2466 r = MsiOpenDatabase(msifile, MSIDBOPEN_READONLY, &hdb2);
2467 ok(r == ERROR_SUCCESS , "Failed to create database\n");
2469 query = "INSERT INTO `Property` ( `Property`, `Value` ) VALUES ( 'prop', 'val' )";
2470 r = run_query(hdb1, 0, query);
2471 ok(r == ERROR_SUCCESS, "failed to add property\n");
2473 /* database needs to be committed */
2474 MsiDatabaseCommit(hdb1);
2476 r = MsiDatabaseGenerateTransform(hdb1, hdb2, mstfile, 0, 0);
2477 ok(r == ERROR_SUCCESS, "return code %d, should be ERROR_SUCCESS\n", r);
2479 #if 0 /* not implemented in wine yet */
2480 r = MsiCreateTransformSummaryInfo(hdb2, hdb2, mstfile, 0, 0);
2481 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2482 #endif
2484 MsiCloseHandle(hdb1);
2485 MsiCloseHandle(hdb2);
2488 /* data for generating a transform */
2490 /* tables transform names - encoded as they would be in an msi database file */
2491 static const WCHAR name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }; /* _StringData */
2492 static const WCHAR name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }; /* _StringPool */
2493 static const WCHAR name3[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }; /* Property */
2495 /* data in each table */
2496 static const char data1[] = /* _StringData */
2497 "propval"; /* all the strings squashed together */
2499 static const WCHAR data2[] = { /* _StringPool */
2500 /* len, refs */
2501 0, 0, /* string 0 '' */
2502 4, 1, /* string 1 'prop' */
2503 3, 1, /* string 2 'val' */
2506 static const WCHAR data3[] = { /* Property */
2507 0x0201, 0x0001, 0x0002,
2510 static const struct {
2511 LPCWSTR name;
2512 const void *data;
2513 DWORD size;
2514 } table_transform_data[] =
2516 { name1, data1, sizeof data1 - 1 },
2517 { name2, data2, sizeof data2 },
2518 { name3, data3, sizeof data3 },
2521 #define NUM_TRANSFORM_TABLES (sizeof table_transform_data/sizeof table_transform_data[0])
2523 static void generate_transform_manual(void)
2525 IStorage *stg = NULL;
2526 IStream *stm;
2527 WCHAR name[0x20];
2528 HRESULT r;
2529 DWORD i, count;
2530 const DWORD mode = STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
2532 const CLSID CLSID_MsiTransform = { 0xc1082,0,0,{0xc0,0,0,0,0,0,0,0x46}};
2534 MultiByteToWideChar(CP_ACP, 0, mstfile, -1, name, 0x20);
2536 r = StgCreateDocfile(name, mode, 0, &stg);
2537 ok(r == S_OK, "failed to create storage\n");
2538 if (!stg)
2539 return;
2541 r = IStorage_SetClass(stg, &CLSID_MsiTransform);
2542 ok(r == S_OK, "failed to set storage type\n");
2544 for (i=0; i<NUM_TRANSFORM_TABLES; i++)
2546 r = IStorage_CreateStream(stg, table_transform_data[i].name,
2547 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2548 if (FAILED(r))
2550 ok(0, "failed to create stream %08x\n", r);
2551 continue;
2554 r = IStream_Write(stm, table_transform_data[i].data,
2555 table_transform_data[i].size, &count);
2556 if (FAILED(r) || count != table_transform_data[i].size)
2557 ok(0, "failed to write stream\n");
2558 IStream_Release(stm);
2561 IStorage_Release(stg);
2563 set_transform_summary_info();
2566 static void test_transformprop(void)
2568 UINT r;
2570 CreateDirectoryA("msitest", NULL);
2571 create_file("msitest\\augustus", 500);
2573 create_database(msifile, tp_tables, sizeof(tp_tables) / sizeof(msi_table));
2575 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2577 r = MsiInstallProductA(msifile, NULL);
2578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2579 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2580 ok(!delete_pf("msitest", FALSE), "File installed\n");
2582 if (0)
2583 generate_transform();
2584 else
2585 generate_transform_manual();
2587 r = MsiInstallProductA(msifile, "TRANSFORMS=winetest.mst");
2588 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2589 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2590 ok(delete_pf("msitest", FALSE), "File not installed\n");
2592 /* Delete the files in the temp (current) folder */
2593 DeleteFile(msifile);
2594 DeleteFile(msifile2);
2595 DeleteFile(mstfile);
2596 DeleteFile("msitest\\augustus");
2597 RemoveDirectory("msitest");
2600 static void test_currentworkingdir(void)
2602 UINT r;
2603 CHAR path[MAX_PATH];
2604 LPSTR ptr, ptr2;
2606 CreateDirectoryA("msitest", NULL);
2607 create_file("msitest\\augustus", 500);
2609 create_database(msifile, cwd_tables, sizeof(cwd_tables) / sizeof(msi_table));
2611 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2613 CreateDirectoryA("diffdir", NULL);
2614 SetCurrentDirectoryA("diffdir");
2616 sprintf(path, "..\\%s", msifile);
2617 r = MsiInstallProductA(path, NULL);
2618 todo_wine
2620 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
2621 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2622 ok(!delete_pf("msitest", FALSE), "File installed\n");
2625 sprintf(path, "%s\\%s", CURR_DIR, msifile);
2626 r = MsiInstallProductA(path, NULL);
2627 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2628 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2629 ok(delete_pf("msitest", FALSE), "File not installed\n");
2631 lstrcpyA(path, CURR_DIR);
2632 if (path[lstrlenA(path) - 1] != '\\')
2633 lstrcatA(path, "\\");
2634 lstrcatA(path, "msitest.msi");
2636 ptr2 = strrchr(path, '\\');
2637 *ptr2 = '\0';
2638 ptr = strrchr(path, '\\');
2639 *ptr2 = '\\';
2640 *(ptr++) = '\0';
2642 SetCurrentDirectoryA(path);
2644 r = MsiInstallProductA(ptr, NULL);
2645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2646 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
2647 ok(delete_pf("msitest", FALSE), "File not installed\n");
2649 SetCurrentDirectoryA(CURR_DIR);
2651 DeleteFile(msifile);
2652 DeleteFile("msitest\\augustus");
2653 RemoveDirectory("msitest");
2654 RemoveDirectory("diffdir");
2657 static void set_admin_summary_info(const CHAR *name)
2659 MSIHANDLE db, summary;
2660 UINT r;
2662 r = MsiOpenDatabaseA(name, MSIDBOPEN_DIRECT, &db);
2663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2665 r = MsiGetSummaryInformationA(db, NULL, 1, &summary);
2666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2668 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, 5, NULL, NULL);
2669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2671 /* write the summary changes back to the stream */
2672 r = MsiSummaryInfoPersist(summary);
2673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2675 MsiCloseHandle(summary);
2677 r = MsiDatabaseCommit(db);
2678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2680 MsiCloseHandle(db);
2683 static void test_admin(void)
2685 UINT r;
2687 CreateDirectoryA("msitest", NULL);
2688 create_file("msitest\\augustus", 500);
2690 create_database(msifile, adm_tables, sizeof(adm_tables) / sizeof(msi_table));
2691 set_admin_summary_info(msifile);
2693 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2695 r = MsiInstallProductA(msifile, NULL);
2696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2697 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2698 ok(!delete_pf("msitest", FALSE), "File installed\n");
2699 ok(!DeleteFile("c:\\msitest\\augustus"), "File installed\n");
2700 ok(!RemoveDirectory("c:\\msitest"), "File installed\n");
2702 r = MsiInstallProductA(msifile, "ACTION=ADMIN");
2703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2704 ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n");
2705 ok(!delete_pf("msitest", FALSE), "File installed\n");
2706 todo_wine
2708 ok(DeleteFile("c:\\msitest\\augustus"), "File not installed\n");
2709 ok(RemoveDirectory("c:\\msitest"), "File not installed\n");
2712 DeleteFile(msifile);
2713 DeleteFile("msitest\\augustus");
2714 RemoveDirectory("msitest");
2717 static void set_admin_property_stream(LPCSTR file)
2719 IStorage *stg;
2720 IStream *stm;
2721 WCHAR fileW[MAX_PATH];
2722 HRESULT hr;
2723 DWORD count;
2724 const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
2726 /* AdminProperties */
2727 static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
2728 static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
2730 MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
2732 hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
2733 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
2734 if (!stg)
2735 return;
2737 hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2738 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
2740 hr = IStream_Write(stm, data, sizeof(data), &count);
2741 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
2743 IStream_Release(stm);
2744 IStorage_Release(stg);
2747 static void test_adminprops(void)
2749 UINT r;
2751 CreateDirectoryA("msitest", NULL);
2752 create_file("msitest\\augustus", 500);
2754 create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
2755 set_admin_summary_info(msifile);
2756 set_admin_property_stream(msifile);
2758 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2760 r = MsiInstallProductA(msifile, NULL);
2761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2762 ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
2763 ok(delete_pf("msitest", FALSE), "File installed\n");
2765 DeleteFile(msifile);
2766 DeleteFile("msitest\\augustus");
2767 RemoveDirectory("msitest");
2770 static void create_pf(LPCSTR file, BOOL is_file)
2772 CHAR path[MAX_PATH];
2774 lstrcpyA(path, PROG_FILES_DIR);
2775 lstrcatA(path, "\\");
2776 lstrcatA(path, file);
2778 if (is_file)
2779 create_file(path, 500);
2780 else
2781 CreateDirectoryA(path, NULL);
2784 static void test_removefiles(void)
2786 UINT r;
2788 CreateDirectoryA("msitest", NULL);
2789 create_file("msitest\\hydrogen", 500);
2790 create_file("msitest\\helium", 500);
2791 create_file("msitest\\lithium", 500);
2793 create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
2795 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2797 r = MsiInstallProductA(msifile, NULL);
2798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2799 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
2800 ok(!pf_exists("msitest\\helium"), "File installed\n");
2801 ok(pf_exists("msitest\\lithium"), "File not installed\n");
2802 ok(pf_exists("msitest"), "File not installed\n");
2804 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2805 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2806 ok(!pf_exists("msitest\\helium"), "File not deleted\n");
2807 ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
2808 todo_wine
2810 ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
2811 ok(delete_pf("msitest", FALSE), "File deleted\n");
2814 create_pf("msitest", FALSE);
2815 create_pf("msitest\\hydrogen", TRUE);
2816 create_pf("msitest\\helium", TRUE);
2817 create_pf("msitest\\lithium", TRUE);
2819 r = MsiInstallProductA(msifile, NULL);
2820 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2821 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
2822 ok(pf_exists("msitest\\helium"), "File not installed\n");
2823 ok(pf_exists("msitest\\lithium"), "File not installed\n");
2824 ok(pf_exists("msitest"), "File not installed\n");
2826 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2828 ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
2829 ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
2830 todo_wine
2832 ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
2833 ok(delete_pf("msitest", FALSE), "File deleted\n");
2836 create_pf("msitest", FALSE);
2837 create_pf("msitest\\furlong", TRUE);
2838 create_pf("msitest\\firkin", TRUE);
2839 create_pf("msitest\\fortnight", TRUE);
2840 create_pf("msitest\\becquerel", TRUE);
2841 create_pf("msitest\\dioptre", TRUE);
2842 create_pf("msitest\\attoparsec", TRUE);
2843 create_pf("msitest\\storeys", TRUE);
2844 create_pf("msitest\\block", TRUE);
2845 create_pf("msitest\\siriometer", TRUE);
2847 r = MsiInstallProductA(msifile, NULL);
2848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2849 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
2850 ok(!pf_exists("msitest\\helium"), "File installed\n");
2851 ok(pf_exists("msitest\\lithium"), "File not installed\n");
2852 ok(pf_exists("msitest\\becquerel"), "File not installed\n");
2853 ok(pf_exists("msitest\\dioptre"), "File not installed\n");
2854 ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
2855 ok(pf_exists("msitest"), "File not installed\n");
2856 todo_wine
2858 ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
2859 ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
2860 ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
2861 ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
2862 ok(!pf_exists("msitest\\block"), "File not deleted\n");
2863 ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
2866 create_pf("msitest\\furlong", TRUE);
2867 create_pf("msitest\\firkin", TRUE);
2868 create_pf("msitest\\fortnight", TRUE);
2869 create_pf("msitest\\storeys", TRUE);
2870 create_pf("msitest\\block", TRUE);
2871 create_pf("msitest\\siriometer", TRUE);
2873 r = MsiInstallProductA(msifile, "REMOVE=ALL");
2874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2875 ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
2876 ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
2877 ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
2878 ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
2879 ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
2880 ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
2881 ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
2882 todo_wine
2884 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
2885 ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
2886 ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
2887 ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
2888 ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
2890 ok(delete_pf("msitest", FALSE), "File deleted\n");
2892 DeleteFile(msifile);
2893 DeleteFile("msitest\\hydrogen");
2894 DeleteFile("msitest\\helium");
2895 DeleteFile("msitest\\lithium");
2896 RemoveDirectory("msitest");
2899 START_TEST(install)
2901 DWORD len;
2902 char temp_path[MAX_PATH], prev_path[MAX_PATH];
2904 init_functionpointers();
2906 GetCurrentDirectoryA(MAX_PATH, prev_path);
2907 GetTempPath(MAX_PATH, temp_path);
2908 SetCurrentDirectoryA(temp_path);
2910 lstrcpyA(CURR_DIR, temp_path);
2911 len = lstrlenA(CURR_DIR);
2913 if(len && (CURR_DIR[len - 1] == '\\'))
2914 CURR_DIR[len - 1] = 0;
2916 get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
2918 test_MsiInstallProduct();
2919 test_MsiSetComponentState();
2920 test_packagecoltypes();
2921 test_continuouscabs();
2922 test_caborder();
2923 test_mixedmedia();
2924 test_samesequence();
2925 test_uiLevelFlags();
2926 test_readonlyfile();
2927 test_setdirproperty();
2928 test_cabisextracted();
2929 test_concurrentinstall();
2930 test_setpropertyfolder();
2931 test_publish();
2932 test_publishsourcelist();
2933 test_transformprop();
2934 test_currentworkingdir();
2935 test_admin();
2936 test_adminprops();
2937 test_removefiles();
2939 SetCurrentDirectoryA(prev_path);